ComboBox as DataGridTemplateColumn SelectedValue不更新​​绑定属性

时间:2017-11-28 21:14:58

标签: wpf vb.net xaml

我无法将带有DataGrid弹出窗口的CustComboBox(重命名为MultiColumnComboBox)实现到DataGridTemplateColumn: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>

我已尝试将SelectedValue的Binding Mode明确设置为TwoWay,但它没有做任何事情(正如预期的那样,因为TwoWay不需要在MultiColumnCombo的第一个实现中明确设置)

我有什么遗失的东西吗?或者也许我需要添加到Object类或MainWindow代码隐藏的一些添加的编码结构?

For Reference,我的移植版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>

1 个答案:

答案 0 :(得分:0)

找到了让它运转的方法,虽然我不确定它是否效率最高。无论哪种方式,我都将一个依赖属性添加到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设置为&#34; ConnectionT&#34;时,在对嵌套的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>