MVVM框架下,WPF实现Datagrid里的全选和选择

时间:2022-05-18 08:42:47

最近的一个项目是用MVVM实现,在实现功能的时候,就会有一些东西,和以前有很大的区别,项目中就用到了常用的序号,就是在Datagrid里的一个字段,用checkbox来实现。

既然是MVVM,就要用到ModleView,View和Model三层。

先看一下效果

MVVM框架下,WPF实现Datagrid里的全选和选择MVVM框架下,WPF实现Datagrid里的全选和选择

当然,也可以确定是哪一项被选中了,这个代码里有。

实现这个全选功能,用到了三个DLL文件,分别为GalaSoft.MvvmLight.Extras.WPF4.dll,GalaSoft.MvvmLight.WPF4.dll,System.Windows.Interactivity.dll

Model曾需要实现INotifyPropertyChanged接口,以方便向客户端通知属性被更改了

MVVM框架下,WPF实现Datagrid里的全选和选择MVVM框架下,WPF实现Datagrid里的全选和选择
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是用来标识是不是全选中

MVVM框架下,WPF实现Datagrid里的全选和选择MVVM框架下,WPF实现Datagrid里的全选和选择
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层需要 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" ,xmlns:Custom="http://www.galasoft.ch/mvvmlight" 两个命名空间

由于序号是绑定过来的,因此是用了stackpanel把checkbox和label放到了一起

MVVM框架下,WPF实现Datagrid里的全选和选择MVVM框架下,WPF实现Datagrid里的全选和选择
<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

 

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

代码