如何更新WPF组合框时,分配一个对象作为它的SelectedItem

本文关键字:一个对象 分配 SelectedItem 何更新 更新 组合 WPF | 更新日期: 2023-09-27 18:13:16

我有一个ComboBox,它的ItemsSourceObservableCollection<CustomObject>绑定,其中CustomObject具有一些属性。

样本类:

public class CustomObject : INotifyPropertyChanged
{
    public string Property1 { /*...omitted for brevity...*/ }
    public string Property2 { /*...omitted for brevity...*/ }
    public string Property3 { /*...omitted for brevity...*/ }
}

我的ComboBoxSelectedItem属性绑定到CustomObject属性,出现在DataGrid行。

样本类:

public class DataGridEntry : INotifyPropertyChanged
{
    public CustomObject Column1 { /*...omitted for brevity...*/ }
    public string Column2 { /*...omitted for brevity...*/ }
    public string Column3 { /*...omitted for brevity...*/ }
}

我在窗口初始化期间创建ObservableCollection<CustomObject>,然后将DataGrid的数据上下文设置为ObservableCollection<DataGridEntry>

我的目标是将初始值加载到我的DataGrid中,但我不知道如何使ComboBox意识到指定的CustomObject可以在其ItemsSource中找到,因此,ComboBox不呈现SelectedItem

下面是我加载初始值的方法:
ObservableCollection<DataGridEntry> entries = new ObservableCollection<DataGridEntry>();
MyWindow.DataContext = this;
entries.Add(new DataGridEntry(new CustomObject("val1", "val2", "val3"), "col2", "col3");

你知道我是如何让ComboBox像这样设置它的SelectedItem属性吗?如果我更改代码,使DataGridEntry仅与string属性一起工作,那么ComboBox在按我的期望进行初始化后呈现SelectedItem。对于引用类型,它不起作用。


如果需要,下面是我将数据绑定到Combobox的方法:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CustomObjectsCollection}" SelectedItem="{Binding Column1, UpdateSourceTrigger=PropertyChanged}"/>
编辑:


如果不清楚,ObservableCollection<CustomObject>包含一个与上面相同的元素:new CustomObject("val1", "val2", "val3");

我怀疑ComboBox没有意识到两个CustomObjects是等价的。由于这种怀疑,我为CustomObject重写了EqualsGetHashCode函数,但没有成功。显然,ComboBox在检测非引用数据类型(如字符串)的相等性方面没有问题。谢谢你的帮助!:)

如何更新WPF组合框时,分配一个对象作为它的SelectedItem

请记住,GetHashCode()Equals()Object类型比较上工作(即您的ObservableCollection<T>需要用于Object类型)。

对于更强类型的覆盖,您应该实现IEquatable<T> -这应该允许组合框在设置SelectedItem属性时比较项目。

ComboBox正在使用Object.Equals来确定相等性。默认情况下,这意味着ComboBox在使用引用类型时期望使用相同的引用。当使用值类型时,Object.Equals比较值。虽然String在技术上不是一个值类型,但它已经覆盖了Object.Equals来比较值。

String类似,可以通过为ComboBox保存的类类型定义自定义Equals方法来覆盖相等行为。

对于原始帖子中的示例,Equals方法应该这样比较每个属性:

public class CustomObject : INotifyPropertyChanged
{
    //Include properties, constructor, and INotifyPropertyChanged interface members.
    public override bool Equals(object obj)
    {
        CustomObject test = obj as CustomObject;  //test=null if obj cannot be casted.
        if(test == null) return false; //Comparing null against non-null: FALSE
        else
        {   //Check if all properties are equal.
            return ((Property1.CompareTo(test.Property1) == 0) &&
                    (Property2.CompareTo(test.Property2) == 0) &&
                    (Property3.CompareTo(test.Property3) == 0));
        }
    }
}

尽管没有它ComboBox将保持功能。重写Object.GetHashCode也是一个好主意。这超出了本回答的范围,但是,可以在这里找到该函数的文档化实现:

重写System.Object.GetHashCode的最佳算法是什么?