2017-11-28 1 views
1

Ich habe Probleme, diese CustComboBox Umsetzung (umbenannt MultiColumnComboBox) mit einem Datagrid-Popup in einem Datagridtemplatecolumn: https://www.codeproject.com/Articles/43074/WPF-Custom-ComboBoxComboBox als Datagridtemplatecolumn SelectedValue nicht gebundene Eigenschaft Aktualisierung

Hier ist ein Link zu SampleApp warf ich zusammen meine aktuelle Implementierung und Fragen zu zeigen, : https://drive.google.com/file/d/1ChZKjeppf-J04j3RGr6k8tPUE2W8oBBc/view?usp=sharing

im Beispiel habe ich zwei Objekte:

  • ConnectionPair hat 2 String Eigenschaften "Connection" ein d "EQConnection"
  • ToolObj hat eine String-Eigenschaft "ConnectionT"

SampleApp MainWindow.vb:

Private _ToolObjCollection As New ObservableCollection(Of ToolObj) 
    Public Property ToolObjCollection As ObservableCollection(Of ToolObj) 
     Get 
      Return _ToolObjCollection 
     End Get 
     Set(value As ObservableCollection(Of ToolObj)) 
      _ToolObjCollection = value 
     End Set 
    End Property 

    Private _ConnectionPairCollection As New ObservableCollection(Of ConnectionPair) 
    Public Property ConnectionPairCollection As ObservableCollection(Of ConnectionPair) 
     Get 
      Return _ConnectionPairCollection 
     End Get 
     Set(value As ObservableCollection(Of ConnectionPair)) 
      _ConnectionPairCollection = value 
     End Set 
    End Property 

    Private _TestTool As New ToolObj("conn2") 
     Public Property TestTool As ToolObj 
     Get 
      Return _TestTool 
     End Get 
     Set(value As ToolObj) 
      _TestTool = value 
     End Set 
    End Property 

    Sub New() 
     InitializeComponent() 

     _ToolObjCollection.Add(New ToolObj("conn1")) 
     _ToolObjCollection.Add(New ToolObj("conn2")) 

     _ConnectionPairCollection.Add(New ConnectionPair("conn1", "eqconn1")) 
     _ConnectionPairCollection.Add(New ConnectionPair("conn2", "eqconn2")) 

     DataContext = Me 

    End Sub 

Ich möchte Itemssource des Combo Popup zu ConnectionPairCollection binden, und ich möchte die Auswahl um die ConnectionT-Eigenschaft in meinem ToolObj zu aktualisieren.

Wenn Sie dies mit der MultiColumnComboBox außerhalb einer DataGridTemplateColumn tun, scheint alles gut zu funktionieren. Die Umsetzung sieht wie folgt aus:

<local:MultiColumnComboBox 
    DisplayMemberPath="Connection" 
    ItemsSource="{Binding ConnectionPairCollection}" 
    SelectedValue="{Binding TestTool.ConnectionT}" 
    SelectedValuePath="Connection"> 
    <DataGridTextColumn 
     Header="Connection" 
     Binding="{Binding Connection}" /> 
    <DataGridTextColumn 
     Header="EQ Connection" 
     Binding="{Binding EQConnection}" /> 
</local:MultiColumnComboBox> 

Als ich die MultiColumnComboBox in einem Datagridtemplatecolumn eines Datagrid mit seinen Itemssource an ToolObjCollection gebunden setzen, funktioniert die Bindung nur einen Weg. Es empfängt SelectedValue korrekt von meinem ToolObj und registriert die richtige Auswahl in dem Popup, aber das Ändern der Auswahl der ComboBox aktualisiert den Wert von dem ToolObj nicht. Die Umsetzung sieht wie folgt aus:

<DataGrid 
     Margin="0" 
     Grid.Row="1" 
     ItemsSource="{Binding ToolObjCollection}" 
     Tag="{Binding ConnectionPairCollection}"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn 
       Header="TemplatedMultiColumnCombo"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <local:MultiColumnComboBox 
          DisplayMemberPath="Connection" 
          ItemsSource="{Binding DataContext.ConnectionPairCollection, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
          SelectedValue="{Binding ConnectionT}" 
          SelectedValuePath="Connection"> 
          <DataGridTextColumn 
           Header="Connection" 
           Binding="{Binding Connection}" /> 
          <DataGridTextColumn 
           Header="EQ Connection" 
           Binding="{Binding EQConnection}" /> 
         </local:MultiColumnComboBox> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 

Ich habe explizit versucht Bindungsmodus von SelectedValue zu TwoWay Einstellung, aber es tut nichts (wie erwartet, da TwoWay muss nicht explizit in der ersten Implementierung des MultiColumnCombo festgelegt werden)

Gibt es etwas, das mir fehlt? Oder vielleicht eine zusätzliche Codierungsstruktur, die ich entweder der Object-Klasse oder dem MainWindow-Codebehind hinzufügen muss?

Für Reference, meine portierte Version des CustComboBox:

MultiColumnComboBox.vb

' Follow steps 1a or 1b and then 2 to use this custom control in a XAML file. 
' 
' Step 1a) Using this custom control in a XAML file that exists in the current project. 
' Add this XmlNamespace attribute to the root element of the markup file where it is 
' to be used: 
' 
'  xmlns:MyNamespace="clr-namespace:WinSurvWPF" 
' 
' 
' Step 1b) Using this custom control in a XAML file that exists in a different project. 
' Add this XmlNamespace attribute to the root element of the markup file where it is 
' to be used: 
' 
'  xmlns:MyNamespace="clr-namespace:WinSurvWPF;assembly=WinSurvWPF" 
' 
' You will also need to add a project reference from the project where the XAML file lives 
' to this project and Rebuild to avoid compilation errors: 
' 
'  Right click on the target project in the Solution Explorer and 
'  "Add Reference"->"Projects"->[Browse to and select this project] 
' 
' 
' Step 2) 
' Go ahead and use your control in the XAML file. Note that Intellisense in the 
' XML editor does not currently work on custom controls and its child elements. 
' 
'  <MyNamespace:MultiColumnComboBox/> 
' 

Imports System.ComponentModel 
Imports System.Windows.Markup 
Imports System.Collections.ObjectModel 
Imports System.Windows.Controls.Primitives 
Imports System.Runtime.CompilerServices 

''' <summary> 
''' 
''' </summary> 
<DefaultProperty("Columns")> 
<ContentProperty("Columns")> 
Public Class MultiColumnComboBox 
    Inherits ComboBox 
    Implements INotifyPropertyChanged 
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 
    Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing) 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) 
    End Sub 


    Const partPopupDataGrid As String = "PART_PopupDataGrid" 
    'Columns of DataGrid 
    Private _Columns As ObservableCollection(Of DataGridTextColumn) 
    'Attached DataGrid control 
    Private PopupDataGrid As DataGrid 

    Shared Sub New() 
     DefaultStyleKeyProperty.OverrideMetadata(GetType(MultiColumnComboBox), New FrameworkPropertyMetadata(GetType(MultiColumnComboBox))) 
    End Sub 

    'The property is default and Content property for CustComboBox 
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> 
    Public ReadOnly Property Columns() As ObservableCollection(Of DataGridTextColumn) 
     Get 
      If Me._Columns Is Nothing Then 
       Me._Columns = New ObservableCollection(Of DataGridTextColumn)() 
      End If 
      Return Me._Columns 
     End Get 
    End Property 

    'Apply theme and attach columns to DataGrid popupo control 
    Public Overrides Sub OnApplyTemplate() 
     If PopupDataGrid Is Nothing Then 

      PopupDataGrid = TryCast(Me.Template.FindName(partPopupDataGrid, Me), DataGrid) 
      If PopupDataGrid IsNot Nothing AndAlso _Columns IsNot Nothing Then 
       'Add columns to DataGrid columns 
       For i As Integer = 0 To _Columns.Count - 1 
        PopupDataGrid.Columns.Add(_Columns(i)) 
       Next 

       'Add event handler for DataGrid popup 
       PopupDataGrid.AddHandler(PreviewMouseDownEvent, New MouseButtonEventHandler(AddressOf PopupDataGrid_MouseDown)) 

       PopupDataGrid.AddHandler(SelectionChangedEvent, New SelectionChangedEventHandler(AddressOf PopupDataGrid_SelectionChanged)) 
      End If 
     End If 
     'Call base class method 
     MyBase.OnApplyTemplate() 
    End Sub 

    'Synchronize selection between Combo and DataGrid popup 
    Private Sub PopupDataGrid_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) 
     'When open in Blend prevent raising exception 
     If Not DesignerProperties.GetIsInDesignMode(Me) Then 
      Dim dg As DataGrid = TryCast(sender, DataGrid) 
      If dg IsNot Nothing Then 
       Me.SelectedItem = dg.SelectedItem 
       Me.SelectedValue = dg.SelectedValue 
       Me.SelectedIndex = dg.SelectedIndex 

       Me.SelectedValuePath = dg.SelectedValuePath 
      End If 
     End If 
    End Sub 

    'Event for DataGrid popup MouseDown 
    Private Sub PopupDataGrid_MouseDown(sender As Object, e As MouseButtonEventArgs) 
     Dim dg As DataGrid = TryCast(sender, DataGrid) 
     If dg IsNot Nothing Then 
      Dim dep As DependencyObject = DirectCast(e.OriginalSource, DependencyObject) 

      ' iteratively traverse the visual tree and stop when dep is one of .. 
      While (dep IsNot Nothing) AndAlso Not (TypeOf dep Is DataGridCell) AndAlso Not (TypeOf dep Is DataGridColumnHeader) 
       dep = VisualTreeHelper.GetParent(dep) 
      End While 

      If dep Is Nothing Then 
       Return 
      End If 

      ' do something 
      If TypeOf dep Is DataGridColumnHeader Then 
      End If 
      'When user clicks to DataGrid cell, popup have to be closed 
      If TypeOf dep Is DataGridCell Then 
       Me.IsDropDownOpen = False 
      End If 
     End If 
    End Sub 

    'When selection changed in combobox (pressing arrow key down or up) must be synchronized with opened DataGrid popup 
    Protected Overrides Sub OnSelectionChanged(e As SelectionChangedEventArgs) 
     MyBase.OnSelectionChanged(e) 
     If PopupDataGrid Is Nothing Then 
      Return 
     End If 

     If Not DesignerProperties.GetIsInDesignMode(Me) Then 
      If IsDropDownOpen Then 
       PopupDataGrid.SelectedItem = Me.SelectedItem 
       If PopupDataGrid.SelectedItem IsNot Nothing Then 
        PopupDataGrid.ScrollIntoView(PopupDataGrid.SelectedItem) 
       End If 
      End If 
     End If 
    End Sub 
    Protected Overrides Sub OnDropDownOpened(e As EventArgs) 
     PopupDataGrid.SelectedItem = Me.SelectedItem 

     MyBase.OnDropDownOpened(e) 

     If PopupDataGrid.SelectedItem IsNot Nothing Then 
      PopupDataGrid.ScrollIntoView(PopupDataGrid.SelectedItem) 
     End If 

    End Sub 
End Class 

MultiColumnComboBox Ressourcen Wörterbuch:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
    xmlns:local="clr-namespace:SampleApp"> 
    <Style 
     x:Key="ComboBoxFocusVisual"> 
     <Setter 
      Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle 
         Stroke="Black" 
         StrokeDashArray="1 2" 
         StrokeThickness="1" 
         Margin="4,4,21,4" 
         SnapsToDevicePixels="true" /> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <LinearGradientBrush 
     x:Key="ButtonNormalBackground" 
     EndPoint="0,1" 
     StartPoint="0,0"> 
     <GradientStop 
      Color="#F3F3F3" 
      Offset="0" /> 
     <GradientStop 
      Color="#EBEBEB" 
      Offset="0.5" /> 
     <GradientStop 
      Color="#DDDDDD" 
      Offset="0.5" /> 
     <GradientStop 
      Color="#CDCDCD" 
      Offset="1" /> 
    </LinearGradientBrush> 
    <SolidColorBrush 
     x:Key="ButtonNormalBorder" 
     Color="#FF707070" /> 
    <Geometry 
     x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry> 
    <Style 
     x:Key="ComboBoxReadonlyToggleButton" 
     TargetType="{x:Type ToggleButton}"> 
     <Setter 
      Property="OverridesDefaultStyle" 
      Value="true" /> 
     <Setter 
      Property="IsTabStop" 
      Value="false" /> 
     <Setter 
      Property="Focusable" 
      Value="false" /> 
     <Setter 
      Property="ClickMode" 
      Value="Press" /> 
     <Setter 
      Property="Template"> 
      <Setter.Value> 
       <ControlTemplate 
        TargetType="{x:Type ToggleButton}"> 
        <Microsoft_Windows_Themes:ButtonChrome 
         x:Name="Chrome" 
         SnapsToDevicePixels="true" 
         Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         RenderMouseOver="{TemplateBinding IsMouseOver}" 
         RenderPressed="{TemplateBinding IsPressed}"> 
         <Grid 
          HorizontalAlignment="Right" 
          Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"> 
          <Path 
           x:Name="Arrow" 
           Fill="Black" 
           HorizontalAlignment="Center" 
           Margin="3,1,0,0" 
           VerticalAlignment="Center" 
           Data="{StaticResource DownArrowGeometry}" /> 
         </Grid> 
        </Microsoft_Windows_Themes:ButtonChrome> 
        <ControlTemplate.Triggers> 
         <Trigger 
          Property="IsChecked" 
          Value="true"> 
          <Setter 
           Property="RenderPressed" 
           TargetName="Chrome" 
           Value="true" /> 
         </Trigger> 
         <Trigger 
          Property="IsEnabled" 
          Value="false"> 
          <Setter 
           Property="Fill" 
           TargetName="Arrow" 
           Value="#AFAFAF" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <LinearGradientBrush 
     x:Key="TextBoxBorder" 
     EndPoint="0,20" 
     StartPoint="0,0" 
     MappingMode="Absolute"> 
     <GradientStop 
      Color="#ABADB3" 
      Offset="0.05" /> 
     <GradientStop 
      Color="#E2E3EA" 
      Offset="0.07" /> 
     <GradientStop 
      Color="#E3E9EF" 
      Offset="1" /> 
    </LinearGradientBrush> 
    <Style 
     x:Key="ComboBoxEditableTextBox" 
     TargetType="{x:Type TextBox}"> 
     <Setter 
      Property="OverridesDefaultStyle" 
      Value="true" /> 
     <Setter 
      Property="AllowDrop" 
      Value="true" /> 
     <Setter 
      Property="MinWidth" 
      Value="0" /> 
     <Setter 
      Property="MinHeight" 
      Value="0" /> 
     <Setter 
      Property="FocusVisualStyle" 
      Value="{x:Null}" /> 
     <Setter 
      Property="Template"> 
      <Setter.Value> 
       <ControlTemplate 
        TargetType="{x:Type TextBox}"> 
        <ScrollViewer 
         x:Name="PART_ContentHost" 
         Background="Transparent" 
         Focusable="false" 
         HorizontalScrollBarVisibility="Hidden" 
         VerticalScrollBarVisibility="Hidden" /> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <Style 
     x:Key="ComboBoxToggleButton" 
     TargetType="{x:Type ToggleButton}"> 
     <Setter 
      Property="OverridesDefaultStyle" 
      Value="true" /> 
     <Setter 
      Property="IsTabStop" 
      Value="false" /> 
     <Setter 
      Property="Focusable" 
      Value="false" /> 
     <Setter 
      Property="ClickMode" 
      Value="Press" /> 
     <Setter 
      Property="Template"> 
      <Setter.Value> 
       <ControlTemplate 
        TargetType="{x:Type ToggleButton}"> 
        <Microsoft_Windows_Themes:ButtonChrome 
         x:Name="Chrome" 
         Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" 
         SnapsToDevicePixels="true" 
         Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         RenderMouseOver="{TemplateBinding IsMouseOver}" 
         RenderPressed="{TemplateBinding IsPressed}" 
         RoundCorners="false"> 
         <Path 
          x:Name="Arrow" 
          Fill="Black" 
          HorizontalAlignment="Center" 
          Margin="0,1,0,0" 
          VerticalAlignment="Center" 
          Data="{StaticResource DownArrowGeometry}" /> 
        </Microsoft_Windows_Themes:ButtonChrome> 
        <ControlTemplate.Triggers> 
         <Trigger 
          Property="IsChecked" 
          Value="true"> 
          <Setter 
           Property="RenderPressed" 
           TargetName="Chrome" 
           Value="true" /> 
         </Trigger> 
         <Trigger 
          Property="IsEnabled" 
          Value="false"> 
          <Setter 
           Property="Fill" 
           TargetName="Arrow" 
           Value="#AFAFAF" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <ControlTemplate 
     x:Key="ComboBoxEditableTemplate" 
     TargetType="{x:Type local:MultiColumnComboBox}"> 
     <Grid 
      x:Name="Placement" 
      SnapsToDevicePixels="true"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition 
        Width="*" /> 
       <ColumnDefinition 
        Width="Auto" /> 
      </Grid.ColumnDefinitions> 
      <Popup 
       x:Name="PART_Popup" 
       AllowsTransparency="true" 
       IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" 
       Placement="Bottom" 
       PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" 
       Grid.ColumnSpan="2"> 
       <Microsoft_Windows_Themes:SystemDropShadowChrome 
        x:Name="Shdw" 
        MaxHeight="{TemplateBinding MaxDropDownHeight}" 
        MinWidth="{Binding ActualWidth, ElementName=Placement}" 
        Color="Transparent"> 
        <Border 
         x:Name="DropDownBorder" 
         Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" 
         BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" 
         BorderThickness="1"> 
         <DataGrid 
          x:Name="PART_PopupDataGrid" 
          ItemsSource="{TemplateBinding ItemsSource}" 
          AutoGenerateColumns="False" 
          IsReadOnly="True" 
          IsSynchronizedWithCurrentItem="False" 
          SelectionMode="Single" 
          HeadersVisibility="Column" 
          SelectedIndex="{TemplateBinding SelectedIndex}" 
          DisplayMemberPath="{TemplateBinding DisplayMemberPath}" 
          Focusable="False" 
          SelectedItem="{TemplateBinding SelectedItem}" 
          SelectedValue="{TemplateBinding SelectedValue}" 
          SelectedValuePath="{TemplateBinding SelectedValuePath}" 
          RowDetailsVisibilityMode="Collapsed" 
          Tag="{TemplateBinding Tag}" 
          MaxHeight="{TemplateBinding MaxDropDownHeight}" 
          IsTextSearchEnabled="{TemplateBinding IsTextSearchEnabled}" 
          CanUserSortColumns="True"> 
         </DataGrid> 
        </Border> 
       </Microsoft_Windows_Themes:SystemDropShadowChrome> 
      </Popup> 
      <Microsoft_Windows_Themes:ListBoxChrome 
       x:Name="Border" 
       Grid.ColumnSpan="2" 
       Background="{TemplateBinding Background}" 
       BorderBrush="{TemplateBinding BorderBrush}" 
       BorderThickness="{TemplateBinding BorderThickness}" 
       RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" 
       RenderMouseOver="{TemplateBinding IsMouseOver}" /> 
      <TextBox 
       x:Name="PART_EditableTextBox" 
       Margin="{TemplateBinding Padding}" 
       Style="{StaticResource ComboBoxEditableTextBox}" 
       HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
       VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" 
       IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" /> 
      <ToggleButton 
       Style="{StaticResource ComboBoxToggleButton}" 
       Grid.Column="1" 
       IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" /> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger 
       Property="IsKeyboardFocusWithin" 
       Value="true"> 
       <Setter 
        Property="Foreground" 
        Value="Black" /> 
      </Trigger> 
      <Trigger 
       Property="IsDropDownOpen" 
       Value="true"> 
       <Setter 
        Property="RenderFocused" 
        TargetName="Border" 
        Value="true" /> 
      </Trigger> 
      <Trigger 
       Property="HasItems" 
       Value="false"> 
       <Setter 
        Property="Height" 
        TargetName="DropDownBorder" 
        Value="95" /> 
      </Trigger> 
      <Trigger 
       Property="IsEnabled" 
       Value="false"> 
       <Setter 
        Property="Foreground" 
        Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" /> 
       <Setter 
        Property="Background" 
        Value="#FFF4F4F4" /> 
      </Trigger> 
      <Trigger 
       Property="IsGrouping" 
       Value="true"> 
       <Setter 
        Property="ScrollViewer.CanContentScroll" 
        Value="false" /> 
      </Trigger> 
      <Trigger 
       Property="HasDropShadow" 
       SourceName="PART_Popup" 
       Value="true"> 
       <Setter 
        Property="Margin" 
        TargetName="Shdw" 
        Value="0,0,5,5" /> 
       <Setter 
        Property="Color" 
        TargetName="Shdw" 
        Value="#71000000" /> 
      </Trigger> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 
    <Style 
     TargetType="{x:Type local:MultiColumnComboBox}"> 
     <Setter 
      Property="FocusVisualStyle" 
      Value="{StaticResource ComboBoxFocusVisual}" /> 
     <Setter 
      Property="Foreground" 
      Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" /> 
     <Setter 
      Property="Background" 
      Value="{StaticResource ButtonNormalBackground}" /> 
     <Setter 
      Property="BorderBrush" 
      Value="{StaticResource ButtonNormalBorder}" /> 
     <Setter 
      Property="BorderThickness" 
      Value="1" /> 
     <Setter 
      Property="ScrollViewer.HorizontalScrollBarVisibility" 
      Value="Auto" /> 
     <Setter 
      Property="ScrollViewer.VerticalScrollBarVisibility" 
      Value="Auto" /> 
     <Setter 
      Property="Padding" 
      Value="4,3" /> 
     <Setter 
      Property="Template"> 
      <Setter.Value> 
       <ControlTemplate 
        TargetType="{x:Type local:MultiColumnComboBox}"> 
        <Grid 
         x:Name="MainGrid" 
         SnapsToDevicePixels="true"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition 
           Width="*" /> 
          <ColumnDefinition 
           MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" 
           Width="0" /> 
         </Grid.ColumnDefinitions> 
         <Popup 
          x:Name="PART_Popup" 
          Margin="1" 
          AllowsTransparency="true" 
          IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" 
          Placement="Bottom" 
          PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" 
          Grid.ColumnSpan="2"> 
          <Microsoft_Windows_Themes:SystemDropShadowChrome 
           x:Name="Shdw" 
           MaxHeight="{TemplateBinding MaxDropDownHeight}" 
           MinWidth="{Binding ActualWidth, ElementName=MainGrid}" 
           Color="Transparent"> 
           <Border 
            x:Name="DropDownBorder" 
            Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" 
            BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" 
            BorderThickness="1"> 
            <DataGrid 
             x:Name="PART_PopupDataGrid" 
             ItemsSource="{TemplateBinding ItemsSource}" 
             AutoGenerateColumns="False" 
             IsReadOnly="True" 
             IsSynchronizedWithCurrentItem="False" 
             SelectionMode="Single" 
             HeadersVisibility="Column" 
             SelectedIndex="{TemplateBinding SelectedIndex}" 
             DisplayMemberPath="{TemplateBinding DisplayMemberPath}" 
             Focusable="False" 
             SelectedItem="{TemplateBinding SelectedItem}" 
             SelectedValue="{TemplateBinding SelectedValue}" 
             SelectedValuePath="{TemplateBinding SelectedValuePath}" 
             RowDetailsVisibilityMode="Collapsed" 
             Tag="{TemplateBinding Tag}" 
             MaxHeight="{TemplateBinding MaxDropDownHeight}" 
             IsTextSearchEnabled="{TemplateBinding IsTextSearchEnabled}" 
             CanUserSortColumns="False" /> 
           </Border> 
          </Microsoft_Windows_Themes:SystemDropShadowChrome> 
         </Popup> 
         <ToggleButton 
          Style="{StaticResource ComboBoxReadonlyToggleButton}" 
          Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          Grid.ColumnSpan="2" 
          IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" /> 
         <ContentPresenter 
          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
          Margin="{TemplateBinding Padding}" 
          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
          IsHitTestVisible="false" 
          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
          Content="{TemplateBinding SelectionBoxItem}" 
          ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" 
          ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" /> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger 
          Property="HasDropShadow" 
          SourceName="PART_Popup" 
          Value="true"> 
          <Setter 
           Property="Margin" 
           TargetName="Shdw" 
           Value="0,0,5,5" /> 
          <Setter 
           Property="Color" 
           TargetName="Shdw" 
           Value="#71000000" /> 
         </Trigger> 
         <Trigger 
          Property="HasItems" 
          Value="false"> 
          <Setter 
           Property="Height" 
           TargetName="DropDownBorder" 
           Value="95" /> 
         </Trigger> 
         <Trigger 
          Property="IsEnabled" 
          Value="false"> 
          <Setter 
           Property="Foreground" 
           Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" /> 
          <Setter 
           Property="Background" 
           Value="#FFF4F4F4" /> 
         </Trigger> 
         <Trigger 
          Property="IsGrouping" 
          Value="true"> 
          <Setter 
           Property="ScrollViewer.CanContentScroll" 
           Value="false" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Style.Triggers> 
      <Trigger 
       Property="IsEditable" 
       Value="true"> 
       <Setter 
        Property="BorderBrush" 
        Value="{StaticResource TextBoxBorder}" /> 
       <Setter 
        Property="Background" 
        Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" /> 
       <Setter 
        Property="IsTabStop" 
        Value="false" /> 
       <Setter 
        Property="Padding" 
        Value="3" /> 
       <Setter 
        Property="Template" 
        Value="{StaticResource ComboBoxEditableTemplate}" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</ResourceDictionary> 

Antwort

0

Ich habe einen Weg gefunden, damit es funktioniert, obwohl ich nicht sicher bin, ob es am effizientesten ist.So oder so, habe ich eine Abhängigkeitseigenschaft der MultiColumnComboBox Steuerung: BindingPath als String:

Public Shared ReadOnly BindingPathProperty As DependencyProperty = 
    DependencyProperty.Register("BindingPath", GetType(String), GetType(MultiColumnComboBox)) 
Public Property BindingPath As String 
    Get 
     Return GetValue(BindingPathProperty) 
    End Get 
    Set(value As String) 
     SetValue(BindingPathProperty, value) 
    End Set 
End Property 

Dann habe ich die Selection Event-Handler für einen Satz BindingPath Wert, und legen Sie die Zieleigenschaft über CallByName zu überprüfen geändert:

Private Sub PopupDataGrid_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) 
    If Not DesignerProperties.GetIsInDesignMode(Me) Then 
     Dim dg As DataGrid = TryCast(sender, DataGrid) 
     If dg IsNot Nothing Then 
      Me.SelectedItem = dg.SelectedItem 
      Me.SelectedValue = dg.SelectedValue 
      Me.SelectedIndex = dg.SelectedIndex 
      Me.SelectedValuePath = dg.SelectedValuePath 

      If BindingPath IsNot Nothing Then 
       CallByName(Me.DataContext, BindingPath, CallType.Set, Me.SelectedValue) 
      End If 
     End If 
    End If 
End Sub 

wenn nun BindingPath des MultiColumnCombo auf "ConnectionT" -Einstellung, alles richtig aktualisiert, wenn die Optionen auf die verschachtelten MultiColumnCombo machen ..

<DataGrid 
     Margin="0" 
     Grid.Row="1" 
     ItemsSource="{Binding ToolObjCollection}" 
     Tag="{Binding ConnectionPairCollection}"> 
     <DataGrid.Resources> 
      <local:BindingProxy 
       x:Key="proxy" 
       Data="{Binding}" /> 
     </DataGrid.Resources> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn 
       Header="TemplatedMultiColumnCombo"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <local:MultiColumnComboBox 
          DisplayMemberPath="Connection" 
          ItemsSource="{Binding Data.ConnectionPairCollection, Source={StaticResource proxy}}" 
          BindingPath="ConnectionT" 
          SelectedValue="{Binding ConnectionT}" 
          SelectedValuePath="Connection"> 
          <DataGridTextColumn 
           Header="Connection" 
           Binding="{Binding Connection}" /> 
          <DataGridTextColumn 
           Header="EQ Connection" 
           Binding="{Binding EQConnection}" /> 
         </local:MultiColumnComboBox> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
0

Das Problem ist, dass die Datacontext in einem nicht zugänglich ist DataGridTemplateColumn. Dies geschieht für Elemente, die nicht Teil des visuellen oder logischen Baums sind. Sie können ein BindingProxy verwenden, um es zu lösen. Here ist, wie Sie dies tun können.

+0

I tri Dies umzusetzen, aber es scheint nichts zu ändern. Ich sehe, wie ich es verwenden könnte, um die ItemsSource der ComboBox (also den Popup-Inhalt) an die ConnectionPairCollection in meinem MainWindow zu binden, aber das ist nicht die Bindung, die mir Probleme bereitet. Die Bindung, die mir Probleme macht, ist die ToolObjCollection, und ich bin mir nicht sicher, wie Sie in dieser Situation einen verbindlichen Proxy dafür verwenden. Vielleicht kannst du es ausarbeiten? – misterkiem

Verwandte Themen