如何根据组合框的ID而不是对象本身来绑定选中的项

本文关键字:绑定 对象 组合 何根 ID | 更新日期: 2023-09-27 18:18:01

考虑以下标记(最后三个标签仅用于开发目的,以便我可以验证绑定正在执行我认为的操作)。

<ComboBox x:Name="TimeFrame"
          DisplayMemberPath="Name"
          ItemsSource="{Binding TimeFrames}"
          SelectedItem="{Binding Path=Order.TimeFrame}"
          SelectionChanged="Combox_OnSelectionChanged" />
<Label Content="{Binding Path=Order.TimeFrame.Name}"></Label>
<Label Content="{Binding Path=Order.TimeFrame.Id}"></Label>
<Label Content="{Binding Path=Order.TimeFrameId}"></Label>

一切正常,更改的选项被更新到数据库并被正确恢复。所有标签都按预期填充。有一件事是错误的,在组合框中选择的项目没有正确设置。因为我可以看到它是正确的绑定,所以我假设对象比较失败,因为存储在顺序中的对象是组合框中对象的副本,但不是同一个实例

我在时间框架上使用部分类解决了这个问题,如下所示。

public partial class TimeFrame
{
  public override bool Equals(object input)
  {
    TimeFrame comparee = input as TimeFrame;
    return comparee != null && comparee.Id == Id;
  }
  public override int GetHashCode()
  {
    return base.GetHashCode();
  }
}

果然有效,这进一步表明我的结论是正确的。现在我有两个问题。

  1. 是否有一种方法可以从标记进行比较(即不覆盖相等性检查)?
  2. 我应该担心比较失败,因为这些对象是不同的实例(代码气味风险)?

如何根据组合框的ID而不是对象本身来绑定选中的项

Selector及其后代不喜欢,当非空SelectedItem不在ItemsSource中时

假设您正在使用视图模型,那么在加载视图模型时,最好将Order.TimeFrameTimeFrames同步。即:

if (Order.TimeFrame != null)
{
    Order.TimeFrame = TimeFrames.SingleOrDefault(_ => _.Id == Order.TimeFrame.Id);
}

这也将正确处理Order.TimeFrame.Id不在TimeFrames id中的情况。

我认为你应该为SelectedTimeFrame添加一个属性并绑定到它。

<ComboBox x:Name="TimeFrame"
      DisplayMemberPath="Name"
      ItemsSource="{Binding TimeFrames}"
      SelectedItem="{Binding Path=SelectedTimeFrame }"
      SelectionChanged="Combox_OnSelectionChanged" />

在属性setter中更新Order.TimeFrame