Wpf 如何将组合框的SelectedItem绑定到作为ItemsSource中项目副本的对象?
我在WPF中使用MVVM模式,遇到了一个问题,我可以将其简化为以下内容: 我有一个卡片式的模型Wpf 如何将组合框的SelectedItem绑定到作为ItemsSource中项目副本的对象?,wpf,xaml,mvvm,data-binding,combobox,Wpf,Xaml,Mvvm,Data Binding,Combobox,我在WPF中使用MVVM模式,遇到了一个问题,我可以将其简化为以下内容: 我有一个卡片式的模型 public class CardType { public int Id { get; set; } public string Name { get; set; } } 我有一个使用CardType的viewmodel public class ViewModel : INotifyPropertyChanged { private CardType selectedCa
public class CardType
{
public int Id { get; set; }
public string Name { get; set; }
}
我有一个使用CardType的viewmodel
public class ViewModel : INotifyPropertyChanged
{
private CardType selectedCardType;
public CardType SelectedCardType
{
get { return selectedCardType; }
set
{
selectedCardType = value;
OnPropertyChanged(nameof(SelectedCardType));
}
}
public IEnumerable<CardType> CardTypes { get; set; }
// ... and so on ...
}
我的XAML有一个组合框,它的项目基于CardType,并且应该根据SelectedCardType预先选择一个项目
public class ViewModel : INotifyPropertyChanged
{
private CardType selectedCardType;
public CardType SelectedCardType
{
get { return selectedCardType; }
set
{
selectedCardType = value;
OnPropertyChanged(nameof(SelectedCardType));
}
}
public IEnumerable<CardType> CardTypes { get; set; }
// ... and so on ...
}
<ComboBox ItemsSource="{Binding CardTypes}"
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedCardType}"/>
由于我无法控制的原因,SelectedCardType对象将是CardTypes中项目的引用副本。因此,WPF无法将SelectedItem与ItemsSource中的项目匹配,并且当我运行应用程序时,组合框最初会显示,但未选择任何项目
我尝试在CardType上重写Equals和GetHashCode方法,但WPF仍然无法匹配这些项
鉴于我的特殊限制,如何让ComboBox选择正确的项目?一种解决方法是将SelectedItem绑定到字符串而不是cardType,然后使用此字符串创建cardType类型的对象?您可以使用SelectedValue和SelectedValuePath:
<ComboBox ItemsSource="{Binding CardTypes}"
DisplayMemberPath="Name"
SelectedValue="{Binding ProductId, Mode=TwoWay}"
SelectedValuePath="Id"/>
其中ProductId是NotifyPropertyChanged的int属性
请在此处阅读一个很好的解释:
您可能没有正确覆盖Equals和GetHashCode。这应该对你有用。然而,在您的情况下,只重写Equals是可行的,但是当您为类重写Equals时,重写GetHashCode也是一种好的做法
public class CardType
{
public int Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
CardType cardType = obj as CardType;
return cardType.Id == Id && cardType.Name == Name;
}
public override int GetHashCode()
{
return Id.GetHashCode() & Name.GetHashCode();
}
}
这需要我将viewmodel的SelectedCardType属性更改为整数,但我无法自由执行此操作。好的,可以肯定,使用此方法,您至少需要添加一个整数。我很快在小样本中进行了尝试,效果非常好。您可以添加如何从代码中设置SelectedCardType的代码吗?Id.GetHashCode可以被替换为Id。虽然最热门的答案有效,但这:是解决同一问题的更优雅的方法。