将对象分配为其SelectedItem时如何更新WPF组合框? [英] How to update a WPF ComboBox when assigning an object as its SelectedItem?

查看:118
本文介绍了将对象分配为其SelectedItem时如何更新WPF组合框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ComboBox,它的ItemsSource绑定到ObservableCollection<CustomObject>,其中CustomObject具有一些属性.

I have a ComboBox which has its ItemsSource bound to an ObservableCollection<CustomObject> where CustomObject has a few properties.

示例类别:

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

我的ComboBoxSelectedItem属性绑定到显示在DataGrid行中的CustomObject属性.

The SelectedItem property of my ComboBox is bound to a CustomObject property which appears in a DataGrid row.

示例类别:

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>.

I create the ObservableCollection<CustomObject> during the initialization of my window and then set the data context of my DataGrid to an ObservableCollection<DataGridEntry>.

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

My objective is to load initial values into my DataGrid, but I do not know how to make the ComboBox realize that the CustomObject specified can be found in its ItemsSource, and consequently, the ComboBox does not render a SelectedItem.

这是我加载初始值的方式:

Here is how I load the initial values:

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.对于引用类型,它不起作用.

Do you know how I make the ComboBox set its SelectedItem property like this? If I change my code so that DataGridEntry works only with string properties, then the ComboBox renders the SelectedItem after initializing as I expect. For reference types, it is not working though.


如果需要,这就是我将数据绑定到Combobox:


In case it is needed, this is how I bind the data to the 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");


In case it is not clear, the ObservableCollection<CustomObject> contains an element which is instatiated the same as above: new CustomObject("val1", "val2", "val3");

我怀疑ComboBox没有意识到两个CustomObjects是等效的.由于这种怀疑,我为CustomObject覆盖了EqualsGetHashCode函数,但没有成功.显然,ComboBox在检测非参考数据类型(例如字符串)是否相等时没有问题. 谢谢您的帮助! :)

I suspect that the ComboBox doesn't realize that the two CustomObjects are equivalent. And because of this suspicion, I overrode the Equals and GetHashCode functions for CustomObject, with no success. Apparently, the ComboBox has no problem detecting equality for non-reference data types such as strings. Thanks for the help! :)

推荐答案

ComboBox使用Object.Equals来确定相等性.默认情况下,这意味着ComboBox在使用引用类型时期望相同​​的引用.使用值类型时,Object.Equals比较值.尽管String从技术上讲不是值类型,但它已覆盖Object.Equals来比较值.

The ComboBox is using Object.Equals to determine equality. By default, this means that the ComboBox expects identical references when working with reference types. When working with value types, Object.Equals compares the values. Although String is not technically a value type, it has overridden Object.Equals to compare values.

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

Similar to String, the equality behavior can be overridden by defining a custom Equals method for the class type the ComboBox holds.

对于原始帖子中的示例,Equals方法应按如下方式比较每个属性:

For the example in the original post, the Equals method should compare each property as such:

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.这超出了此答案的范围,但是,可以在此处找到该功能的详细记录的实现:

Although the ComboBox will remain functional without it. It is a good idea to override Object.GetHashCode as well. This is out of the scope of this answer, however, a well documented implementation of this function can be found here:

被覆盖的System.Object.GetHashCode的最佳算法是什么?

这篇关于将对象分配为其SelectedItem时如何更新WPF组合框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆