WPF: ComboBox,基于标识属性比较对象

4
假设我有一个类,我们称之为Parent。这个类有一个属性,另一个类的对象,我们称之为Child。Child有一个int属性ID。
现在这些类的实例是基于数据库表中的行。
所以假设Parent有一个Child实例,它的ID=4,在我的程序中将有一个下拉列表,其中包含所有可用的Child实例,以便我们可以更改Parent中的实例。
问题在于,由于设计不良,所有子对象的列表是在与Parent内部的Child不同的场合实例化的,因此即使它们都具有ID=4,它也无法将它们识别为相同的对象(因为当然它们不是同一个对象)。
但是,我仍然希望相同ID的对象成为ComboBox的默认对象。当然,我应该以某种方式引用ID,但是在十二月的黑暗月份里,我有点慢,我看不到如何做到这一点,因为它仍然是我设置的对象而不仅仅是int值。
以下是XAML代码:
 <DataTemplate x:Key="EditTemplate" DataType="{x:Type data:Parent}">
      <ComboBox ItemsSource="{Binding ElementName=Panel, Path=DataContext.ChildList}"
                              SelectedItem="{Binding Path=Child, Mode=TwoWay}"
                              SelectedValuePath="ID" DisplayMemberPath="Name" />
 </DataTemplate>

1
我认为这不是一个糟糕的设计。在应用程序的生命周期中,对象可以被多次获取,并且它们将具有不同的地址。我认为这是在任何UI框架中开发应用程序时都会遇到的常见问题。在Vue中,有v-bind:key - Konrad
2个回答

7

即使它们都有ID=4,它也不会将它们视为同一对象(因为它们确实不是同一个对象)

听起来问题的根本在于相等性,重写给定子对象所需的方法以达到符合您需求的相等性定义。

public override bool Equals(object obj)
   {
      Child other = obj as Child;
      if( other == null )
      {
         return false;
      }
 
      return (this.Id == other.Id);
   }
 
   public override int GetHashCode()
   {
      return this.Id.GetHashCode();
   }
 
   public static bool operator == (Child me, Child other)
   {
      return Equals(me, other);
   }
 
   public static bool operator != (Child me, Child other)
   {
      return !Equals(me, other);
   }

嗯,当然应该可以。我一直在寻找 XAML 的解决方案,但这个当然可以工作,而且更加优雅。 - Ingó Vals
覆盖Equals方法就足够了吗?不是的。https://dev59.com/12s05IYBdhLWcg3wQvuq - ed22

5

如果有人再次遇到此问题并需要 XAML 解决方案,您还可以使用 SelectedValuePath 和 SelectedValue 属性以及 SelectedItem 属性。

<DataTemplate x:Key="EditTemplate" DataType="{x:Type data:Parent}">
  <ComboBox ItemsSource="{Binding ElementName=Panel, Path=DataContext.ChildList}"
                          SelectedItem="{Binding Path=Child, Mode=TwoWay}"
                          SelectedValue="{Binding Path=Child.ID, Mode=OneWay}"
                          SelectedValuePath="ID" DisplayMemberPath="Name" />
</DataTemplate>

注意:显然,将选择绑定到两个位置不是最佳实践,使用时请小心。


谢谢!不知道它是如何工作的细节,但它能够正常运转 :-) - Endrju
对我不起作用。但覆盖相等性是有效的。 - ed22
那跟问题中的代码有什么不同? - Konrad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接