为 UWP ComboBox 设置 SelectedItem
Set SelectedItem for UWP ComboBox
UWP ComboBox ItemsSource 显示正确,但未在列表中选择 SelectedItem。为什么会这样?
XAML:
<ComboBox Name="FooComboBox"
ItemsSource="{x:Bind ViewModel.Foos}"
SelectedItem="{x:Bind ViewModel.Foo,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
ChangeTypeConverter
来自 Template10
Foos
和属性的值Foo
是在ViewModel
中设置的
public class ViewModel : ViewModelBase
{
Foo _Foo = default(Foo);
public Foo Foo { get { return _Foo; } set { Set(ref _Foo, value); } }
public ObservableCollection<Foo> Foos = new ObservableCollection<Foo>(FooService.GetFoos());
public ViewModel()
{
Foo = FooService.GetDefaultFoo();
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 是 ViewModel 时,我只会考虑使用它来解决 SelectedItem 问题。
另一种解决方案是在源列表中查找实际项目:
public ObservableCollection<Foo> Foos = ...;
public ViewModel()
{
var d = FooService.GetDefaultFoo();
Foo = Foos.FirstOrDefault(f => f.FooId == d.FooId);
}
UWP ComboBox ItemsSource 显示正确,但未在列表中选择 SelectedItem。为什么会这样?
XAML:
<ComboBox Name="FooComboBox"
ItemsSource="{x:Bind ViewModel.Foos}"
SelectedItem="{x:Bind ViewModel.Foo,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
ChangeTypeConverter
来自 Template10
Foos
和属性的值Foo
是在ViewModel
public class ViewModel : ViewModelBase
{
Foo _Foo = default(Foo);
public Foo Foo { get { return _Foo; } set { Set(ref _Foo, value); } }
public ObservableCollection<Foo> Foos = new ObservableCollection<Foo>(FooService.GetFoos());
public ViewModel()
{
Foo = FooService.GetDefaultFoo();
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 是 ViewModel 时,我只会考虑使用它来解决 SelectedItem 问题。
另一种解决方案是在源列表中查找实际项目:
public ObservableCollection<Foo> Foos = ...;
public ViewModel()
{
var d = FooService.GetDefaultFoo();
Foo = Foos.FirstOrDefault(f => f.FooId == d.FooId);
}