Search code examples
c#wpfdata-bindingdatagriddatagridcomboboxcolumn

WPF DataGrid - Dynamically Bind DataGridComboBoxColumn based on row


I have an ObservableCollection of objects. These object are displayed in a DataGrid & a `SelectedObject

I have a property PossibleParentObjects that returns a List of Objects based on the SelectedObject.

I would like to have this property populate a ComboBox residing in a column of the DataGrid

How can I do this?

Here is what I have so far... Obviously not working:

    <DataGrid   Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            AlternatingRowBackground="AntiqueWhite" AlternationCount="2"
            ItemsSource="{Binding AllObjects, UpdateSourceTrigger=PropertyChanged}"
            SelectedItem="{Binding SelectedObject}"
            CanUserAddRows="True" CanUserDeleteRows="True"
            AutoGenerateColumns="False">

    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name, Mode=TwoWay}" Header="Name"/>
        <DataGridTextColumn Binding="{Binding Abbr, Mode=TwoWay}" Header="Abbreviation"/>
        <DataGridComboBoxColumn Header="Parent Object" Width="120" 
            SelectedItemBinding="{Binding Path=Id, UpdateSourceTrigger=PropertyChanged}"
            DisplayMemberPath="Name"
            ItemsSource="{Binding Path=AllObjects, 
              RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">                    
        </DataGridComboBoxColumn>
        <DataGridTextColumn Binding="{Binding Desc, Mode=TwoWay}" Header="Description"/>
    </DataGrid.Columns>

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="CurrentCellChanged">
            <i:InvokeCommandAction Command="{Binding DataGridChanged}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

</DataGrid>

Solution

  • see this Stackoverflow question which discusses a similar problem.

    The basic idea is the following:

    • bind the datagrid column to a single property in your viewmodel, let's call it "ParentObjects"
    • bind the selected row of the datagrid to another property in the viewmodel. In the setter of that property you should retrieve the data-items you need for the combo box of the DataGridComboBox column, and use this to set the "ParentObjects" property

    This way, whenever the user changes the row he wants to see, it will automatically retrieve the correct objects and populate the combobox column. In other words, you don't retrieve it using the source of the combo box but you retrieve upon change of the selected row. You'll have to do this - the property system does not allow parameters.

    I know it is a general description I give here, not code, but I think you'll get the gist.