如何在 WPF CellTemplate 中使用 DisplayMemberPath?
How to use DisplayMemberPath in WPF CellTemplate?
在 DataGrid 中,其中一列是帐户。我想 select AccountId 但 ComboBox 应该显示 AccountNames。所以我在下面创建了 xaml。它按要求工作,但有一个缺点。如果我更改帐户并转到同一行中的另一个单元格,则 AccountName 尚未更新。 (如果我离开该行,则会根据新的 AccountId 计算和更新 AccountName。)
如果我只将 CellTemplate 与 ComboBox 一起使用,那么我就回避了这个问题,但我不喜欢这个解决方案,因为在不需要时显示 ComboBox 并不好。我可以在离开单元格时尝试更新 AccountName,但我的数据库视图会这样做,此时当前行中可能有错误。因此,我想根据 AccountId 在 CellTemplate 中将 selected AccountName 显示为 TextBlock。 (我试图将 ComboBox 放入 TextBlock,但 TextBlock 不仅显示 selected AccountName,还显示 ComboBox 本身。)
<DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding AccountName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource TextBlockError}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}"
SelectedValue="{Binding AccountId, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"
SelectedValuePath="Id"
DisplayMemberPath="Name"
Style="{StaticResource ComboBoxError}" IsEditable="True"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
您应该绑定到数据对象的 Account
属性 并实现 INotifyPropertyChanged 接口。您可能还想将 UpdateSourceTrigger
属性 设置为 PropertyChanged
:
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}"
SelectedItem="{Binding Account, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
Style="{StaticResource ComboBoxError}" IsEditable="True"/>
- @mm8的回答对我帮助很大。
- 到目前为止,我的模型文件中只有 int AccountId。
- 我介绍了在数据库中创建外键的帐户帐户导航属性。
- (我正在使用实体框架。)
- 更新数据库时,Account 没有改变,只有 AccountId。
- (否则数据库有问题,EF 认为它应该插入一个新帐户而不是使用现有帐户。)
- 现在帐户 属性 的 setter 也更改了 AccountId。
- 帐户实现 IEquatable
- 否则不显示ComboBox的初始值
最后xaml(使用SelectedItem="{Binding Account}" and Text="{Binding Account.Name}")
<DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Account.Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource TextBlockError}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}"
SelectedItem="{Binding Account, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"
DisplayMemberPath="Name"
Style="{StaticResource ComboBoxError}" IsEditable="True"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip">
<Setter.Value>
<TextBlock Text ="{Binding Account.Name}" TextWrapping="Wrap" MaxWidth="300"/>
</Setter.Value>
</Setter>
</Style>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
在 DataGrid 中,其中一列是帐户。我想 select AccountId 但 ComboBox 应该显示 AccountNames。所以我在下面创建了 xaml。它按要求工作,但有一个缺点。如果我更改帐户并转到同一行中的另一个单元格,则 AccountName 尚未更新。 (如果我离开该行,则会根据新的 AccountId 计算和更新 AccountName。)
如果我只将 CellTemplate 与 ComboBox 一起使用,那么我就回避了这个问题,但我不喜欢这个解决方案,因为在不需要时显示 ComboBox 并不好。我可以在离开单元格时尝试更新 AccountName,但我的数据库视图会这样做,此时当前行中可能有错误。因此,我想根据 AccountId 在 CellTemplate 中将 selected AccountName 显示为 TextBlock。 (我试图将 ComboBox 放入 TextBlock,但 TextBlock 不仅显示 selected AccountName,还显示 ComboBox 本身。)
<DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding AccountName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource TextBlockError}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}"
SelectedValue="{Binding AccountId, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"
SelectedValuePath="Id"
DisplayMemberPath="Name"
Style="{StaticResource ComboBoxError}" IsEditable="True"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
您应该绑定到数据对象的 Account
属性 并实现 INotifyPropertyChanged 接口。您可能还想将 UpdateSourceTrigger
属性 设置为 PropertyChanged
:
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}"
SelectedItem="{Binding Account, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
Style="{StaticResource ComboBoxError}" IsEditable="True"/>
- @mm8的回答对我帮助很大。
- 到目前为止,我的模型文件中只有 int AccountId。
- 我介绍了在数据库中创建外键的帐户帐户导航属性。
- (我正在使用实体框架。)
- 更新数据库时,Account 没有改变,只有 AccountId。
- (否则数据库有问题,EF 认为它应该插入一个新帐户而不是使用现有帐户。)
- 现在帐户 属性 的 setter 也更改了 AccountId。
- 帐户实现 IEquatable
- 否则不显示ComboBox的初始值
最后xaml(使用SelectedItem="{Binding Account}" and Text="{Binding Account.Name}")
<DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Account.Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBlockError}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}" SelectedItem="{Binding Account, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" DisplayMemberPath="Name" Style="{StaticResource ComboBoxError}" IsEditable="True"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> <DataGridTemplateColumn.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="ToolTip"> <Setter.Value> <TextBlock Text ="{Binding Account.Name}" TextWrapping="Wrap" MaxWidth="300"/> </Setter.Value> </Setter> </Style> </DataGridTemplateColumn.CellStyle> </DataGridTemplateColumn>