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