将对象分配为其SelectedItem时如何更新WPF组合框? [英] How to update a WPF ComboBox when assigning an object as its SelectedItem?
问题描述
我有一个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...*/ }
}
我的ComboBox
的SelectedItem
属性绑定到显示在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
覆盖了Equals
和GetHashCode
函数,但没有成功.显然,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屋!