WPF_ComboBox的MVVM绑定(一)
WPF_ComboBox的MVVM绑定(二)
WPF_ComboBox的MVVM绑定(三)
在控件ComboBox中,我们一般会将选择项写在ComboBoxItem中,例如:
<ComboBox>
<ComboBoxItem Content="Item0" />
<ComboBoxItem Content="Item1" />
<ComboBoxItem Content="Item2" />
<ComboBoxItem Content="Item3" />
</ComboBox>
这样在界面上我们就会看到“Item0”、“Item1”、“Item2”、“Item3”之类的选项,但是我们选择ComboBoxItem之后,实际想要的的数据并不是“Item0”、“Item1”、“Item2”、“Item3”等在界面显示的字符串,还需要进一步做转换才能得到想要的数据。
但是如果将ComboBox做集合绑定,那么每一个ComboBoxItem就对应集合中的每一个元素,ComboBox中有一个DisplayMemberPath属性,这个属性就是用于界面显示的数据类型,可以将集合元素中的一个属性类型赋值给DisplayMemberPath属性。ComboBox中还有一个SelectedValuePath属性,用于指定在集合元素中被选中的值的类型,对应的SelectedValue属性的值就是就是这个指定的类型的值。
直接上代码:
public class ComboBoxItemModel<T>
{
public string Description { get; set; }
public T SelectedModel { get; set; }
public bool IsEnable { get; set; }
}
这里用了一个泛型,就是我们选择一项后需要的数据类型,一般用的多的是int类型,当然还可以自定义。在这个例子中,我们自定义了一个Person类使用。
public class Person
{
public string Name { get; set; }
public Decimal Salary { get; set; }
}
然后就是ViewModel层,我这里偷了一个懒就直接使用了MainWindow类。实际使用中需要写在自定义的ViewModel中。
public partial class MainWindow : Window,INotifyPropertyChanged
{
public List<ComboBoxItemModel<Person>> list { get; set; }
private Person selectedModel;
public Person SelectedModel
{
get { return selectedModel; }
set
{
selectedModel = value;
OnPropertyChanged();
Console.WriteLine($"{ value.Name} {value.Salary}");
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
list = new List<ComboBoxItemModel<Person>>
{
new ComboBoxItemModel<Person>{Description="Item0",SelectedModel=new Person{ Name="张三",Salary=10000m },IsEnable=true},
new ComboBoxItemModel<Person>{Description="Item1",SelectedModel=new Person{ Name="李四",Salary=10000m },IsEnable=false},
new ComboBoxItemModel<Person>{Description="Item2",SelectedModel=new Person{ Name="赵五",Salary=10000m },IsEnable=true},
new ComboBoxItemModel<Person>{Description="Item3",SelectedModel=new Person{ Name="孙六",Salary=10000m },IsEnable=false},
new ComboBoxItemModel<Person>{Description="Item4",SelectedModel=new Person{ Name="王七",Salary=10000m },IsEnable=true},
};
SelectedModel = list[0].SelectedModel;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName=null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
最后使我们的View层:
<Window
x:Class="TestSolution.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:local="clr-namespace:TestSolution"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="500"
Height="400"
mc:Ignorable="d">
<Grid>
<ComboBox
HorizontalAlignment="Center"
VerticalAlignment="Center"
DisplayMemberPath="Description"
ItemsSource="{Binding list}"
SelectedValue="{Binding SelectedModel}"
SelectedValuePath="SelectedModel">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding IsEnable}" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
</Grid>
</Window>
除了在背景章节中讲到的DisplayMemberPath和SelectedValuePath外。我们将SelectedValue属性也做了绑定,这个绑定的值才是我们真正需要的数据,在这个数据的Set访问器中我们可以获取到那个数据。
我们还可以看到在ComboBoxItemModel类中还有一个IsEnable属性,这个属性主要是考虑到有些ComboBoxItem可能在某些时候需要隐藏或者灰掉,所以使用了这个属性就是绑定,如果需要隐藏则需要绑定Visibility属性。