当ComboBox中的项目是数据库中的自定义对象时,我似乎无法在ComboBox中显示当前选定的值。我把以下测试ViewModel和View放在一起。 SimpleWidgets和ObjectWidgets按预期运行。 CodeWidgets(从数据库中检索为自定义' Code'对象的列表)从不显示SelectedCodeWidget。
public class TestViewModel:BaseTabViewModel
{
private List<int> simpleWidgets;
public List<int> SimpleWidgets
{
get { return simpleWidgets; }
set
{
simpleWidgets = value;
NotifyOfPropertyChange(() => SimpleWidgets);
}
}
private int selectedSimpleWidget;
public int SelectedSimpleWidget
{
get { return selectedSimpleWidget; }
set
{
selectedSimpleWidget = value;
NotifyOfPropertyChange(() => SelectedSimpleWidget);
}
}
private List<Widget> objectWidgets;
public List<Widget> ObjectWidgets
{
get { return objectWidgets; }
set
{
objectWidgets = value;
NotifyOfPropertyChange(() => ObjectWidgets);
}
}
private Widget _selectedObjectWidget;
public Widget SelectedObjectWidget
{
get { return _selectedObjectWidget; }
set
{
_selectedObjectWidget = value;
NotifyOfPropertyChange(() => SelectedObjectWidget);
}
}
private List<ICode> codeWidgets;
public List<ICode> CodeWidgets
{
get { return codeWidgets; }
set
{
codeWidgets = value;
NotifyOfPropertyChange(() => CodeWidgets);
}
}
private Code _selectedCodeWidget;
public Code SelectedCodeWidget
{
get { return _selectedCodeWidget; }
set
{
_selectedCodeWidget = value;
NotifyOfPropertyChange(() => SelectedCodeWidget);
}
}
public TestViewModel()
{
DisplayName = "Test Data";
IsEnabled = true;//control this with permissions
//Simple int comboBox
SimpleWidgets = new List<int> {1, 3, 5, 7, 9};
SelectedSimpleWidget = 7;
//Object filled ComboBox
ObjectWidgets= new List<Widget>();
Widget w = new Widget {Key = 2, Description = "test2"};
ObjectWidgets.Add(w);
w = new Widget { Key = 4, Description = "test4" };
ObjectWidgets.Add(w);
w = new Widget {Key = 6, Description = "test6"};
ObjectWidgets.Add(w);
SelectedObjectWidget = w;
//Code filled ComboBox
CodeWidgets = (new Code().Get("UPFLTY").Result).ToList();
SelectedCodeWidget = new Code(2707);
}
}
public class Widget
{
public int Key { get; set; }
public string Description { get; set; }
}
TestView.xaml是:
<UserControl x:Class="CAB.DataManager.App.Views.TestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UniformGrid>
<ComboBox Name="SimpleWidgets"></ComboBox>
<ComboBox Name="ObjectWidgets"
DisplayMemberPath="Description" >
</ComboBox>
<ComboBox x:Name="CodeWidgets">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Description}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</UniformGrid>
</UserControl>
SimpleWidgets和ObjectWidgets显示所选值,并在下拉列表中包含所有值。 CodeWidgets为空,但下拉列表中包含所有值。我错过了什么?
答案 0 :(得分:3)
WPF的ComboBox通过引用将SelectedItem与ItemsSource中的那些进行比较,在您的情况下,new Code(2707)
的实例与内存中的实例不完全相同(new Code().Get("UPFLTY").Result).ToList()
避免这种情况的最常见方法是在具有通用对象类型的内容上使用SelectedValue
和SelectedValuePath
。
例如,
<ComboBox x:Name="CodeWidgets"
SelectedValue="{Binding SelectedCodeId}"
SelectedValuePath="Id">
另一种解决方案是确保将SelectedItem设置为ItemsSource中的一个项目,而不是该项目的新实例。
SelectedCodeWidget = CodeWidgets.FirstOrDefault(() => p.Id == 2707);
第三种解决方案(通常不建议)是覆盖对象的.Equals
,以便将项目与引用之外的其他内容进行比较
public override bool Equals(object obj)
{
if (obj == null || !(obj is Code))
return false;
return ((Code)obj).Id == this.Id);
}
请注意,如果你走这条路,你也应该覆盖.GetHashCode()
。
答案 1 :(得分:1)
SelectedItem
中的实例必须存在于 ItemsSource
中。
从您的代码中
//Code filled ComboBox
CodeWidgets = (new Code().Get("UPFLTY").Result).ToList();
SelectedCodeWidget = new Code(2707); // THIS is where you bugged!
您可以看到SelectedCodeWidget
设置为Code
的新实例,该实例不在CodeWidgets
中。
答案只是执行以下操作:
//Code filled ComboBox
CodeWidgets = (new Code().Get("UPFLTY").Result).ToList();
var selectedCode = FindCodeByDERP(CodeWidgets, 2707); // MAKE THIS METHOD
SelectedCodeWidget = selectedCode;
FindCodeByDERP
是您编写的一种方法,用于搜索CodeWidgets
中的实例,并返回最强 2707 的实例。不管它是什么意思。我的意思是,你有一个代码 UPFLTY 但是你创建另一个传入 2707 的实例......这没有任何意义。呀。