最近的一個項目是用MVVM實現,在實現功能的時候,就會有一些東西,和之前有很大的區別,項目中就用到了經常使用的序號,就是在Datagrid裏的一個字段,用checkbox來實現。express
既然是MVVM,就要用到ModleView,View和Model三層。mvvm
先看一下效果ide
固然,也能夠肯定是哪一項被選中了,這個代碼裏有。this
實現這個全選功能,用到了三個DLL文件,分別爲GalaSoft.MvvmLight.Extras.WPF4.dll,GalaSoft.MvvmLight.WPF4.dll,System.Windows.Interactivity.dllspa
Model曾須要實現INotifyPropertyChanged接口,以方便向客戶端通知屬性被更改了code
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,是用來肯定是否選中的。xml
ViewModel層繼承ViewModelBase,它來自GalaSoft.MvvmLight命名空間,重點是用到了裏面的RaisePropertyChangedblog
全選的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>
當時實現這個功能的時候也花了很多時間,但願給須要的人一點幫助。