MVVM没有.cs后台逻辑,一般依靠command驱动逻辑及通过binding(vm层的属性)来显示前端
我的数据类Student有三个属性int StuId ,string StuName ,bool isChecked。
首先第一步创建一个UserControl,里面放一个ComboBox
<ComboBox x:Name="cb" Width="150" Height="25" ItemsSource="{Binding StudentList}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Click="CheckBox_Click" IsChecked="{Binding IsChecked,Mode=TwoWay}"/>
<TextBlock Text="{Binding StuName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
ComboBox 的样式改造如前篇非MvvM模式下的改造一样,只要将template中ContentPresenter的Content="{TemplateBinding SelectionBoxItem}"改成Content="{TemplateBinding Tag}"即可。
然后在UserControl.cs里加一个依赖属性
public List<Student> SelectedItems1
{
get { return (List<Student>)GetValue(SelectedItems1Property); }
set { SetValue(SelectedItems1Property, value); }
}
public static readonly DependencyProperty SelectedItems1Property =
DependencyProperty.Register("SelectedItems1", typeof(List<Student>), typeof(ComboboxEx),new PropertyMetadata(null,new PropertyChangedCallback(OnSelectedChangeCallBack)));
private static void OnSelectedChangeCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MessageBox.Show("Success");
}
这里在回调函数中做了个弹出框的处理,用来判断属性绑定是否成功。
勾选框的逻辑处理:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
var items = this.cb.ItemsSource ;
if (items != null )
{
SelectedStr=string.Empty;
foreach (Student item in items)
{
if (item.IsChecked == true)
{
SelectedStr = string.Format("{0}{1};", SelectedStr, item.StuName);
}
}
this.cb.Tag = SelectedStr;
}
}
第二步,建立ViewModel层
里面创建两个属性,一个用来创建数据源集合,一个用来存放勾选的集合
public ObservableCollection<Student> StudentList{get;set;}
private List<Student> _SelectedItems;
public List<Student> SelectedItems
{
get { return _SelectedItems; }
set
{
if (PropertyChanged != null)
{
_SelectedItems = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("SelectedItems"));
}
}
}
建立一个command及一个遍历方法
public ICommand CheckItemsChangedCommand { get; set; }
public void UpdataSelecteditems()
{
List<Student> slist = new List<Student>();
foreach (var item in StudentList)
{
if (item.IsChecked == true)
{
slist.Add(item);
}
}
SelectedItems = slist;
}
在ViewModel构造函数中绑定数据集合,实例化Command;
public ComboboxViewModel()
{
SelectedItems = new List<Student>();
StudentList = new ObservableCollection<Student>()
{
new Student(){StuId=1,StuName="aaa"},
new Student(){StuId=2,StuName="bbb"},
new Student(){StuId=3,StuName="ccc"},
new Student(){StuId=3,StuName="ddd"},
new Student(){StuId=3,StuName="eee"}
};
CheckItemsChangedCommand = new ActionCommand(this.UpdataSelecteditems);
}
最后一步完成部件的组装
<StackPanel>
<UserControls:ComboboxEx x:Name="cb" SelectedItems1="{Binding SelectedItems}"></UserControls:ComboboxEx>
<Button HorizontalAlignment="Center" Content="Click" Command="{Binding CheckItemsChangedCommand}"/>
</StackPanel>
后台加 this.DataContext = new ComboboxViewModel();
(PS:当在Selecte ComboboxItem而非Check的时候,combobox head会显示checkbox。这里要重现ComboboxItem的onMouseLeftUp事件,里面改成e.handle =true即可)