none
DataGridComboBoxColumn set ItemSource based on selected item of another DataGridComboBoxColumn RRS feed

  • Question

  • I have 2 DataGridComboBoxColumn in my datagrid ClassificationComboBox & DisclosureNoteComboBox. The first one works ok, I see it populated with data. What i want is that when an item is selected in the first one i.e. ClassificationComboBox , I want the second one to display a list of data from the selected Item in the first one. The selected Item in ClassificationComboBox is of type Classification and this has a list called ClassificationRecords which I want populated in the DisclosureNoteComboBox.

    This is a snippet of my XML.

      <materialDesign:DataGridComboBoxColumn Header="Classification" IsEditable="False" x:Name="ClassificationComboBox"
                                                           ItemsSourceBinding="{Binding ElementName=TrialBalanceViewName, Path=Report.Classifications}"
                                                           DisplayMemberPath="Name"
                                                           SelectedValuePath="Id" 
                                                           SelectedValueBinding="{Binding ClassificationRecord.ClassificationId}"
                                                           />
                    <materialDesign:DataGridComboBoxColumn Header="Disclosure Note" IsEditable="False" x:Name="DisclosureNoteComboBox"
                                                           ItemsSourceBinding="{Binding ElementName=ClassificationComboBox, Path=SelectedItemBinding.ClassificationRecords}"
                                                           SelectedValuePath="DisclosureNote"
                                                           SelectedValueBinding="{Binding ClassificationRecord.DisclosureNote}"
                                                           />

    I suspect my problem is how to construct the ItemsSourceBinding for the second one (especially the path). I think this is wrong but I am unsure how to call the selected Item of the first one and call ClassificationRecords on it to be the ItemSource of the second one

    ItemsSourceBinding="{Binding ElementName=ClassificationComboBox, Path=SelectedItemBinding.ClassificationRecords}"

    Sunday, January 19, 2020 6:23 PM

All replies

  • Hi,
    try this demo:

    XAML:

    <Window x:Class="Window67"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window67" Height="450" Width="800">
      <Window.Resources>
        <local:Window67VM x:Key="vm"/>
      </Window.Resources>
      <Grid DataContext="{StaticResource vm}">
        <DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="False" CanUserAddRows="False">
          <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Classification"
                                    ItemsSource="{Binding Classifications, Source={StaticResource vm}}"
                                    DisplayMemberPath="Name"
                                    SelectedValuePath="ID"
                                    SelectedValueBinding="{Binding FK}"/>
            <DataGridTemplateColumn Header="DisclosureNote">
              <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                  <ComboBox ItemsSource="{Binding DisclosureNotes}" 
                            DisplayMemberPath="NoteName"
                            SelectedValuePath="ID"
                            SelectedValue="{Binding FKDisclosureNote}"                        />
                </DataTemplate>
              </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
          </DataGrid.Columns>
        </DataGrid>
      </Grid>
    </Window>

    and classes:

    Imports System.Collections.ObjectModel
    Imports System.ComponentModel
    
    Public Class Window67VM
    
      Private cvs As New CollectionViewSource
      Public ReadOnly Property View As ICollectionView
        Get
          If cvs.Source Is Nothing Then cvs.Source = GetData()
          Return cvs.View
        End Get
      End Property
    
      Private cvsClassification As New CollectionViewSource
      Public ReadOnly Property Classifications As ICollectionView
        Get
          If cvsClassification.Source Is Nothing Then cvsClassification.Source = GetClassifications()
          Return cvsClassification.View
        End Get
      End Property
    
      Private Function GetData() As ObservableCollection(Of Data)
        Dim col As New ObservableCollection(Of Data)
        For i = 1 To 10
          Dim d As New Data With {.FK = i, .FKDisclosureNote = 1}
          For k = 1 To 10
            d.DisclosureNotes.Add(New DisclosureNote With {.ID = k, .NoteName = $"DisclosureNote {i} {k}"})
          Next
          col.Add(d)
        Next
        Return col
      End Function
    
      Private Function GetClassifications() As Object
        Dim col As New ObservableCollection(Of Classification)
        For i = 1 To 10
          col.Add(New Classification With {.ID = i, .Name = $"Classification {i}"})
        Next
        Return col
      End Function
    
      Public Class Data
        Public Property FK As Integer
        Public Property FKDisclosureNote As Integer
        Public Property DisclosureNotes As New ObservableCollection(Of DisclosureNote)
      End Class
    
      Public Class Classification
        Public Property ID As Integer
        Public Property Name As String
      End Class
    
      Public Class DisclosureNote
        Public Property ID As Integer
        Public Property NoteName As String
      End Class
    
    End Class


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Sunday, January 19, 2020 9:08 PM