Mvvm 为UWP组合框设置SelectedItem
UWP组合框项目资源显示正确,但列表中未选择SelectedItem。为什么会这样 XAML:Mvvm 为UWP组合框设置SelectedItem,mvvm,uwp,uwp-xaml,template10,Mvvm,Uwp,Uwp Xaml,Template10,UWP组合框项目资源显示正确,但列表中未选择SelectedItem。为什么会这样 XAML: <ComboBox Name="FooComboBox" ItemsSource="{x:Bind ViewModel.Foos}" SelectedItem="{x:Bind ViewModel.Foo,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/> 一个Foo看起来像这样 public
<ComboBox Name="FooComboBox"
ItemsSource="{x:Bind ViewModel.Foos}"
SelectedItem="{x:Bind ViewModel.Foo,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
一个Foo看起来像这样
public class Foo
{
public Guid FooId { get; set; } = Guid.NewGuid();
public string FooCode { get; set; }
public override string ToString()
{
return FooCode;
}
}
然而,尽管
FooComboBox
正确地呈现了Foos
的列表,但是SelectedItem
并没有设置为属性Foo
的当前值。为什么会这样?要将评论变成答案
SelectedItem应该是ItemsSource列表中的实际项,由Equals()方法确定。在您的案例中,它是一个单独的实例,尽管它具有相同的Id,但并不被认为是相等的
有几种方法可以解决这一问题,也许解决类似问题的方法是覆盖Equals:
public class Foo
{
...
// untested
public override bool Equals(object obj)
{
Foo other = obj as Foo;
return FooId.Equals(other?.FooId);
}
}
但这对你应用程序的其他部分有影响。当Foo是VIEW模型时,我只考虑使用它来解决选择项问题。
另一个解决方案是在源列表中查找实际项目:
public ObservableCollection<Foo> Foos = ...;
public ViewModel()
{
var d = FooService.GetDefaultFoo();
Foo = Foos.FirstOrDefault(f => f.FooId == d.FooId);
}
publicobservableCollection Foos=。。。;
公共视图模型()
{
var d=FooService.GetDefaultFoo();
Foo=Foos.FirstOrDefault(f=>f.FooId==d.FooId);
}
GetDefaultFoo()是否返回实际在Foos中的实例?例如,验证Foos.Contains(Foo)==true
谢谢@Henk Holterman的提示。我可以看到Foo
在Foo的
中。。。相同的FooId
和FooCode
,但是Foos.Contains(Foo)
返回false
。我在想为什么会这样?我想GetDefaultFoo()从同一个源(Db)获取值,然后创建自己的实例。这是解决这个问题的一个极好的方法。
public ObservableCollection<Foo> Foos = ...;
public ViewModel()
{
var d = FooService.GetDefaultFoo();
Foo = Foos.FirstOrDefault(f => f.FooId == d.FooId);
}