如何在 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>