【问题标题】:How to use DisplayMemberPath in WPF CellTemplate?如何在 WPF CellTemplate 中使用 DisplayMemberPath?
【发布时间】:2020-05-03 07:13:37
【问题描述】:

在 DataGrid 中,其中一列是 Account。我想选择 AccountId,但 ComboBox 应该显示 AccountNames。所以我在下面创建了 xaml。它按要求工作,但有一个缺点。如果我更改帐户并转到同一行中的另一个单元格,则 AccountName 尚未更新。 (如果我离开该行,则会根据新的 AccountId 计算和更新 AccountName。)

如果我只将 CellTemplate 与 ComboBox 一起使用,那么我会避开这个问题,但我不喜欢这种解决方案,因为在不需要时显示 ComboBox 并不好。当我离开单元格时,我可以尝试更新 AccountName,但我的数据库视图会这样做,此时当前行中可能存在错误。因此,我想根据 AccountId 在 CellTemplate 中将选定的 AccountName 显示为 TextBlock。 (我尝试将 ComboBox 放入 TextBlock 中,但 TextBlock 不仅显示所选的 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>

【问题讨论】:

    标签: wpf xaml datagrid


    【解决方案1】:

    您应该绑定到数据对象的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"/>
    

    【讨论】:

    • 我的 DataGrid 绑定到我有 AccountId 的数据库表。这就是我使用 SelectedValue 和 AccountId 的原因。我可以改写我的问题。有没有办法在同一行的另一列(DataGridTextColumn)中绑定选定的DisplayMemberPath(帐户名称,例如汇丰银行)。
    • @IstvanHeckl:除非有 name 属性在您选择另一个要绑定的 id 时更新。设置“db table”的AccountId 属性不会更改TextBlock 绑定到的AccountName 属性。这就是为什么你应该将它们绑定到同一个属性并更新这个。
    • 非常感谢@mm8。根据您的帮助,我可以找到解决方案。
    【解决方案2】:
    • @mm8 的回答对我帮助很大。
    • 到目前为止,我的模型文件中只有 int AccountId。
    • 我介绍了在数据库中创建外键的帐户帐户导航属性。
      • (我正在使用实体框架。)
    • 当数据库更新时,帐户不会只更改 AccountId。
      • (否则db有问题,EF认为应该插入一个新帐户而不是使用现有帐户。)
    • 现在 Account 属性的设置器也更改了 AccountId。
    • Account 实现 IEquatable
      • 否则不显示ComboBox的初始值
    • 最后是 xaml(使用了 SelectedItem="{Binding Account}" 和 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>
      

    【讨论】:

      猜你喜欢
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      相关资源
      最近更新 更多