WPF DataGrid - Dynamically Bind DataGridComboBoxColumn based on row

守給你的承諾、 提交于 2019-12-11 11:08:51

问题


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>

回答1:


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.




回答2:


This is the final code that ended up working for me. It is the "Answer", but it was Nepdev's answer that got me here. Hopefully this will help others out trying to do something similar.

    <DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HeadersVisibility="Column"
      AlternatingRowBackground="AntiqueWhite" AlternationCount="2"
      ItemsSource="{Binding EquipLocations, UpdateSourceTrigger=PropertyChanged}"
      SelectedItem="{Binding SelectedItem}"
      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="Uses Location" Width="120" 
    SelectedValueBinding="{Binding Path=ParentObjectId, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
    SelectedValuePath="Id"
    DisplayMemberPath="Abbr">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, 
                Path=DataContext.AllPossibleObjects}"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, 
                Path=DataContext.PossibleParentObjects}"/>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <i:InvokeCommandAction Command="{Binding DataGridChanged}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </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>


来源:https://stackoverflow.com/questions/31970769/wpf-datagrid-dynamically-bind-datagridcomboboxcolumn-based-on-row

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!