最近的一个项目是用MVVM实现,在实现功能的时候,就会有一些东西,和以前有很大的区别,项目中就用到了常用的序号,就是在Datagrid里的一个字段,用checkbox来实现。
既然是MVVM,就要用到ModleView,View和Model三层。
先看一下效果
当然,也可以确定是哪一项被选中了,这个代码里有。
实现这个全选功能,用到了三个DLL文件,分别为GalaSoft.MvvmLight.Extras.WPF4.dll,GalaSoft.MvvmLight.WPF4.dll,System.Windows.Interactivity.dll
Model曾需要实现INotifyPropertyChanged接口,以方便向客户端通知属性被更改了

public class MainModel:INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void INotifyPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } private int xh; public int Xh { get { return xh; } set { xh = value; } } private string name; public string Name { get { return name; } set { name = value; INotifyPropertyChanged("Name"); } } private int age; public int Age { get { return age; } set { age = value; INotifyPropertyChanged("Age"); } } private bool isSelected; public bool IsSelected { get { return isSelected; } set { isSelected = value; INotifyPropertyChanged("IsSelected"); } } }
Model层里除了Datagrid里显示的序号,姓名和年龄意外,还有一个就是IsSelected,是用来确定是否选中的。
ViewModel层继承ViewModelBase,它来自GalaSoft.MvvmLight命名空间,重点是用到了里面的RaisePropertyChanged
全选的checkbox和下面选中的checkbox是分开来写的,各自有各自的Command,选中和不选中都有,IsSelectAll是用来标识是不是全选中

public class MainViewModel : ViewModelBase { public MainViewModel() { DataGridBaseInfo = AddDataGridInfo(); } /// <summary> /// 给Datagrid绑定的属性 /// </summary> private List<MainModel> dataGridBaseInfo; public List<MainModel> DataGridBaseInfo { get { return dataGridBaseInfo; } set { dataGridBaseInfo = value; RaisePropertyChanged("DataGridBaseInfo"); } } /// <summary> /// 显示按钮 /// </summary> private RelayCommand buttonCommand; public RelayCommand ButtonCommand { get { return buttonCommand ?? (buttonCommand = new RelayCommand( () => { int count = DataGridBaseInfo.ToList().FindAll(p => p.IsSelected == true).Count; MessageBox.Show("选中了" + count + "项"); //for (int i = 0; i < count; i++) // MessageBox.Show(DataGridBaseInfo.ToList().FindAll(p=>p.IsSelected==true)[i].Name + "," + DataGridBaseInfo.ToList().FindAll(p=>p.IsSelected==true)[i].Age); })); } } public List<MainModel> AddDataGridInfo() { MainModel model; List<MainModel> list = new List<MainModel>(); for (int i = 0; i < 5; i++) { model = new MainModel(); model.Xh = i; model.Name = "李雷" + i; model.Age = 20 + i; list.Add(model); } return list; } /// <summary> /// 选中 /// </summary> private RelayCommand selectCommand; public RelayCommand SelectCommand { get { return selectCommand ?? (selectCommand = new RelayCommand( () => { int selectCount = DataGridBaseInfo.ToList().Count(p => p.IsSelected == false); if (selectCount.Equals(0)) { IsSelectAll = true; } })); } } /// <summary> /// 取消选中 /// </summary> private RelayCommand unSelectCommand; public RelayCommand UnSelectCommand { get { return unSelectCommand ?? (unSelectCommand = new RelayCommand( () => { IsSelectAll = false; })); } } private bool isSelectAll = false; public bool IsSelectAll { get { return isSelectAll; } set { isSelectAll = value; RaisePropertyChanged("IsSelectAll"); } } /// <summary> /// 选中全部 /// </summary> private RelayCommand selectAllCommand; public RelayCommand SelectAllCommand { get { return selectAllCommand ?? (selectAllCommand = new RelayCommand(ExecuteSelectAllCommand, CanExecuteSelectAllCommand)); } } private void ExecuteSelectAllCommand() { if (DataGridBaseInfo.Count < 1) return; DataGridBaseInfo.ToList().FindAll(p => p.IsSelected = true); } private bool CanExecuteSelectAllCommand() { if (DataGridBaseInfo != null) { return DataGridBaseInfo.Count > 0; } else return false; } /// <summary> /// 取消全部选中 /// </summary> private RelayCommand unSelectAllCommand; public RelayCommand UnSelectAllCommand { get { return unSelectAllCommand ?? (unSelectAllCommand = new RelayCommand(ExecuteUnSelectAllCommand, CanExecuteUnSelectAllCommand)); } } private void ExecuteUnSelectAllCommand() { if (DataGridBaseInfo.Count < 1) return; if (DataGridBaseInfo.ToList().FindAll(p => p.IsSelected == false).Count != 0) IsSelectAll = false; else DataGridBaseInfo.ToList().FindAll(p => p.IsSelected = false); } private bool CanExecuteUnSelectAllCommand() { if (DataGridBaseInfo != null) { return DataGridBaseInfo.Count > 0; } else { return false; } } }
View层需要 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" ,xmlns:Custom="http://www.galasoft.ch/mvvmlight" 两个命名空间
由于序号是绑定过来的,因此是用了stackpanel把checkbox和label放到了一起

<Grid> <Grid.RowDefinitions> <RowDefinition Height="20"/> <RowDefinition Height="*"/> <RowDefinition Height="20"/> </Grid.RowDefinitions> <DataGrid Grid.Row="1" ItemsSource="{Binding DataGridBaseInfo, Mode=TwoWay}" Margin="10" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.Header> <CheckBox Content="全选" IsChecked="{Binding IsSelectAll,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Checked"> <Custom:EventToCommand Command="{Binding DataContext.SelectAllCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding IsSelectAll, ElementName=qx}"/> </i:EventTrigger> <i:EventTrigger EventName="Unchecked"> <Custom:EventToCommand Command="{Binding DataContext.UnSelectAllCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding IsSelectAll, ElementName=qx}"/> </i:EventTrigger> </i:Interaction.Triggers> </CheckBox> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <CheckBox x:Name="cbXh" VerticalAlignment="Center" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Checked"> <Custom:EventToCommand Command="{Binding DataContext.SelectCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding IsChecked, ElementName=cbXh}"/> </i:EventTrigger> <i:EventTrigger EventName="Unchecked"> <Custom:EventToCommand Command="{Binding DataContext.UnSelectCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding IsChecked, ElementName=cbXh}"/> </i:EventTrigger> </i:Interaction.Triggers> </CheckBox> <Label Content="{Binding Xh}" FontSize="14"/> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="*"/> <DataGridTextColumn Header="年龄" Binding="{Binding Age}" Width="*"/> </DataGrid.Columns> </DataGrid> <Button Content="显示" Grid.Row="2" Width="50" Command="{Binding ButtonCommand}"/> </Grid>
当时实现这个功能的时候也花了不少时间,希望给需要的人一点帮助。