你的位置:首页 > ASP.net教程

[ASP.net教程]MVVM框架下,WPF实现Datagrid里的全选和选择


最近的一个项目是用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

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;      }    }  }

ViewModel

 

View层需要 两个命名空间

由于序号是绑定过来的,因此是用了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>

View

 

当时实现这个功能的时候也花了不少时间,希望给需要的人一点帮助。

代码