ComboBox作为DataGridTemplateColumn的SelectedValue不更新​​绑定属性

我有一个DataGrid弹出窗口到DataGridTemplateColumn实现此CustComboBox(重命名MultiColumnComboBox)时遇到问题:https://www.codeproject.com/Articles/43074/WPF-Custom-ComboBox

这里有一个SampleApp的链接,我将它放在一起展示我目前的实施和问题:https://drive.google.com/file/d/1ChZKjeppf-J04j3RGr6k8tPUE2W8oBBc/view?usp=sharing

在这个例子中,我有两个对象:

  • ConnectionPair有2个字符串属性“Connection”和“EQConnection”
  • ToolObj有一个字符串属性“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
    

    我想将Combo Popup的ItemsSource绑定到ConnectionPairCollection,并且我希望选择更新我的ToolObj上的ConnectionT属性。

    当使用DataGridTemplateColumn之外的MultiColumnComboBox进行此操作时,一切似乎都正常。 实现如下所示:

    <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>
    

    当我将MultiColumnComboBox放置在DataGrid的DataGridTemplateColumn中,并将其ItemsSource绑定到ToolObjCollection时,绑定只能以一种方式工作。 它正确地从我的ToolObj接收SelectedValue,并在弹出窗口中注册适当的选择,但更改ComboBox的选择不会更新ToolObj的值。 实现如下所示:

        <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>
    

    我试着明确地将Binding Mode的SelectedValue设置为TwoWay,但它什么都不做(如预期的那样,因为TwoWay不需要在MultiColumnCombo的第一个实现中明确地设置)

    有什么我失踪? 或者可能是我需要添加到Object类或MainWindow代码隐藏的一些额外的编码结构?

    对于参考,我的移植版本的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资源字典:

    <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>
    

    问题是DataContext无法在DataGridTemplateColumn中访问。 这发生在不属于视觉或逻辑树的元素上。 你可以使用BindingProxy来解决它。 这是你如何做到这一点。


    找到一种方法让它工作,但我不确定它是否最有效。 无论哪种方式,我添加了一个依赖属性到MultiColumnComboBox控件:BindingPath as 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
    

    然后,我修改了SelectionChanged事件处理程序来检查一组BindingPath值,并通过CallByName设置目标属性:

    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
    

    现在,当将MultiColumnCombo的BindingPath设置为“ConnectionT”时,在对嵌套的MultiColumnCombo进行选择时,所有内容都会正确更新。

        <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>
    
    链接地址: http://www.djcxy.com/p/44627.html

    上一篇: ComboBox as DataGridTemplateColumn SelectedValue not updating bound property

    下一篇: WPF Combobox binding and SelectedValue with SelectedValuePath