【问题标题】:Identify object by property instead of reference when binding without overriding Equals在不覆盖 Equals 的情况下绑定时通过属性而不是引用来识别对象
【发布时间】:2019-11-01 03:49:02
【问题描述】:

我希望绑定到 ComboBox 的对象由 Id 而不是引用来标识。无论如何在 XAML 中执行此操作而不覆盖 EqualsGetHashCode

小例子:

XAML:

<ComboBox
    DisplayMemberPath="Name"
    ItemsSource="{Binding People}"
    SelectedValue="{Binding SelectedPerson}"
    SelectedValuePath="Id" />
<Button
    Height="32"
    Click="ButtonBase_OnClick"
    Content="Test assign" />

代码隐藏:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private Person _selectedPerson;

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public Person SelectedPerson
    {
        get => _selectedPerson;
        set
        {
            _selectedPerson = value;
            OnPropertyChanged(nameof(SelectedPerson));
        }
    }

    public ObservableCollection<Person> People { get; set; } = new ObservableCollection<Person>
    {
        new Person { Id = 1, Name = "Angelina Jolie"},
        new Person { Id = 2, Name = "Brad Pitt"}
    };

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        SelectedPerson = new Person {Id = 1, Name = "Angelina Jolie"};
        // SelectedPerson = People[0]; will work but i don't want that 
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

如您所见,我将 SelectedPerson 分配给一个新对象,但名称和 ID 相同,但它不起作用。 ComboBox 仍然通过引用进行比较。

在 Vue 和其他框架中,可以指定一个“键”,用于在绑定时识别对象。 v-bind:keyhttps://vuejs.org/v2/guide/list.html

如果你覆盖EqualsHow do you bind a ComboBox's SelectedItem to an object that is a copy of an item from ItemsSource?,它会起作用,但我想知道是否有任何方法可以避免这种情况。

我希望SelectedValuePath 会做我想做的事,但我错了,它只会影响SelectedValue 的返回值

【问题讨论】:

  • 您为什么反对使用您已经拥有的可以完美解决问题的有效解决方案?
  • @Servy 哪个工作解决方案?你的意思是覆盖Equals
  • 除此之外,您还有其他不愿意使用的可行解决方案吗?
  • 为什么重写一个方法不够简单?这是一行代码,只有几个字符长...如果您也提供 GetHashCode 实现,我猜两行代码,您可能应该这样做。
  • @AvinashReddy 因为在应用程序生命周期内可以多次获取数据并且地址会有所不同。

标签: c# wpf xaml


【解决方案1】:

当你设置时

SelectedValuePath="Id"

SelectedValue 绑定的属性应与Id 的类型相同(与SelectedItem 不同,SelectedItem 应绑定到项目类型的属性)。

例如

SelectedValue="{Binding SelectedPersonId}"

public int SelectedPersonId
{
    get => _selectedPersonId;
    set
    {
        _selectedPersonId = value;
        OnPropertyChanged(nameof(SelectedPersonId));
    }
}

您不需要覆盖EqualsGetHashCode

【讨论】:

    【解决方案2】:

    在不覆盖 Equals 和 GetHashCode 的情况下,是否可以在 XAML 中执行此操作?

    不,没有。

    您可以将ComboBoxSelectedValue 属性绑定到int 源属性,即更改SelectedPerson 的类型,但是如果您想将SelectedItem 属性绑定到Person 属性,你必须覆盖Equals

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-31
      • 2017-11-27
      • 2012-07-08
      • 2021-08-06
      • 2011-02-12
      • 1970-01-01
      • 2018-02-27
      • 2012-09-23
      相关资源
      最近更新 更多