我正在使用MVVM模式在WPF中实现用户控件。我希望控件包含ItemsControl
,特别是ComboBox
,其中包含人员列表。我希望第一个菜单项标记为“No Person'并绑定到数据源上的null
,而其余项是绑定到Person
个对象的人的名称。
Person
的代码和视图模型如下:
namespace NoValueItem
{
public class Person : IEquatable<Person>
{
public int Id { get; set; }
public string Name { get; set; }
public static bool Equals(Person a, Person b)
{
if (a == null)
return b == null;
return a.Equals(b);
}
public bool Equals(Person other)
{
if (ReferenceEquals(this, other))
return true;
if (ReferenceEquals(null, other))
return false;
return this.Name.Equals(other.Name);
}
public override bool Equals(object obj)
{
return Equals(obj as Person);
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
public class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<Person> ListOfPersons { get; } =
new ObservableCollection<Person> {
null,
new Person() { Id = 1, Name = "Alice" },
new Person() { Id = 2, Name = "Bob" },
new Person() { Id = 3, Name = "Charlie" }
};
private Person _SelectedPerson;
public Person SelectedPerson
{
get
{
return _SelectedPerson;
}
set
{
if (!Person.Equals(value, _SelectedPerson)) {
_SelectedPerson = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class NullSubstituteConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value ?? parameter;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter == null)
return value;
return parameter.Equals(value) ? null : value;
}
}
}
观点:
<Window x:Class="NoValueItem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NoValueItem"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid d:DataContext="{d:DesignInstance local:ViewModel}" VerticalAlignment="Center">
<Grid.DataContext>
<local:ViewModel/>
</Grid.DataContext>
<ComboBox ItemsSource="{Binding ListOfPersons}"
SelectedItem="{Binding SelectedPerson}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Window>
在运行时,我按照预期得到4个项目:1个空白菜单项,后跟3个非空白菜单项,Person
集合中每个ViewModel.ListOfPersons
一个,项目文本绑定到Name
的{{1}}属性。
我希望第一个空白项目代替显示文字“没有人”。我怎么能这样做?
我尝试过的一件事是使用以下数据转换器,它将Person
引用转换为转换器参数中指定的对象:
null
然后我对视图进行了以下更改:
namespace NoValueItem
{
public class NullSubstituteConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value ?? parameter;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter == null)
return value;
return parameter.Equals(value) ? null : value;
}
}
}
作为静态资源。NullSubstituteConverter
个对象作为静态资源来代表“无人”。项目并给了关键&#39; NullPerson&#39;。Person
资源设置为转换器,用于绑定ComboBox的NullSubstituteConverter
属性。SelectedItem
资源设置为ComboBox的数据模板中的项目转换器,以便将项目源中的NullSubstituteConverter
项目转换为null
对象。“ / LI>
醇>
这是更新后的视图:
NullPerson
这更接近我想要的。空白菜单项现在显示“没有人”,但仍有2个问题: