WPF DataGrid - 基于行动态绑定 DataGridComboBoxColumn
WPF DataGrid - Dynamically Bind DataGridComboBoxColumn based on row
我有 ObservableCollection
个对象。这些对象显示在一个 DataGrid
和一个 `SelectedObject
我有一个 属性 PossibleParentObjects
returns List
个基于 SelectedObject 的对象。
我想让这个 属性 填充 ComboBox
驻留在 DataGrid
的列中
我该怎么做?
这是我目前所拥有的...显然不工作:
<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>
请参阅讨论类似问题的 this Whosebug question。
基本思路如下:
- 将数据网格列绑定到视图模型中的单个 属性,我们称之为 "ParentObjects"
- 将数据网格的选定行绑定到视图模型中的另一个 属性。
在 属性 的 setter 中,您应该检索 DataGridComboBox 列的组合框所需的数据项,并使用它来设置 "ParentObjects" 属性
这样,每当用户更改他想要查看的行时,它都会自动检索正确的对象并填充组合框列。
换句话说,您不使用组合框的源来检索它,而是在所选行发生更改时进行检索。您必须这样做 - 属性 系统不允许参数。
我知道我在这里给出的是一般描述,而不是代码,但我想您会明白要点。
这是最终为我工作的最终代码。是 "Answer",但正是 Nepdev 的回答让我来到这里。希望这会帮助其他人尝试做类似的事情。
<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>
我有 ObservableCollection
个对象。这些对象显示在一个 DataGrid
和一个 `SelectedObject
我有一个 属性 PossibleParentObjects
returns List
个基于 SelectedObject 的对象。
我想让这个 属性 填充 ComboBox
驻留在 DataGrid
我该怎么做?
这是我目前所拥有的...显然不工作:
<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>
请参阅讨论类似问题的 this Whosebug question。
基本思路如下:
- 将数据网格列绑定到视图模型中的单个 属性,我们称之为 "ParentObjects"
- 将数据网格的选定行绑定到视图模型中的另一个 属性。 在 属性 的 setter 中,您应该检索 DataGridComboBox 列的组合框所需的数据项,并使用它来设置 "ParentObjects" 属性
这样,每当用户更改他想要查看的行时,它都会自动检索正确的对象并填充组合框列。 换句话说,您不使用组合框的源来检索它,而是在所选行发生更改时进行检索。您必须这样做 - 属性 系统不允许参数。
我知道我在这里给出的是一般描述,而不是代码,但我想您会明白要点。
这是最终为我工作的最终代码。是 "Answer",但正是 Nepdev 的回答让我来到这里。希望这会帮助其他人尝试做类似的事情。
<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>