您的位置:首页 > 运维架构 > 网站架构

DataGrid全选功能(使用MVVM架构)

2013-08-27 17:03 253 查看
实现一个DataGrid的Select All的功能,使用的是MVVM架构,完成后的截图如下:



1. 新建一个Silverlight Application,新建一个ViewModels文件夹,在文件夹里添加一个类UserViewModel,该ViewModel是DataGrid显示的每一行的数据的绑定ViewModel。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace SelectAllAndOrder.ViewModels
{
public class UserViewModel:INotifyPropertyChanged
{

public event PropertyChangedEventHandler PropertyChanged;

private static int i = 0;

//带有事件Handler的构造函数,每生成一个新的UserViewModel就给他绑定一个eventHandler
public UserViewModel(PropertyChangedEventHandler eventHandler)
{
this.PropertyChanged += eventHandler;
}

public string Name
{
get { return "Name" + i++; }
}

private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
}
}
}
}
}


2. 新建一个SelectAllViewModel类,用过MainPage的ViewModel使用。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Linq;
using System.Collections.Specialized;

namespace SelectAllAndOrder.ViewModels
{
public class SelectAllViewModel:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

//获取Users集合。ObservableCollection<T>表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。
public ObservableCollection<UserViewModel> Users { get; set; }

public bool IsSelectAll
{
get
{
int userCount = Users.Count;
int selectedUserCount = Users.Count(u => u.IsSelected);
if (userCount == 0) //如果一列没有,则处于不选中状态
{
return false;
}
return userCount == selectedUserCount;//当被选中的人数与总人数相等时处于选中状态
}
set
{
foreach (var user in Users)
{
user.IsSelected = value;
}
}
}

//当前ViewModel的构造函数
public SelectAllViewModel()
{
//默认生成4个UserViewModel对象
//在生成对象的时候注册PropertyChanged事件,这样当某个User被选中时就可以通知SelectAll进行状态更新
Users = new ObservableCollection<UserViewModel>();
Users.Add(new UserViewModel(UserPropertyChanged));
Users.Add(new UserViewModel(UserPropertyChanged));
Users.Add(new UserViewModel(UserPropertyChanged));
Users.Add(new UserViewModel(UserPropertyChanged));

//注册CollectionChanged事件
Users.CollectionChanged += UsersCollectionChanged;
}

public void AddUser()
{
Users.Add(new UserViewModel(UserPropertyChanged));
}

public void DeleteUser()
{
if (Users.Count > 0)
{
Users.RemoveAt(0); //移除最顶端的User
}
}

public void UserPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSelected")
{
//如果是由某一行前面的CheckBox被选中而触发该事件,则通知SelectAll更新事件
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsSelectAll"));
}
}
}

public void UsersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
//如果表格里增加了列或减少了列,也应该通知SelectAll更新状态
//比如先全部选中,然后点击Add Column,这时新增加的列应该不被选中,因此SelectAll也应该不被选中
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsSelectAll"));
}
}
}
}


3. XAML文件的编写,这里注意DataTemlate和CellTemplate的编写:

<UserControl x:Class="SelectAllAndOrder.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
xmlns:sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<UserControl.Resources>
<ResourceDictionary>
<Style x:Key="SelectAllTemplate" TargetType="Primitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding DataContext.IsSelectAll,Mode=TwoWay,ElementName=DataGrid1}"/> <!--这里写ElementName=Layout 也可以-->
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="CheckBoxColumn">
<CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay}"/>
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White" Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="400"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<sdk:DataGrid ItemsSource="{Binding Users}" AutoGenerateColumns="False" IsReadOnly="True" RowHeight="25" CanUserReorderColumns="False" x:Name="DataGrid1">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Width="55" HeaderStyle="{StaticResource SelectAllTemplate}"
CellTemplate="{StaticResource CheckBoxColumn}"></sdk:DataGridTemplateColumn>
<sdk:DataGridTextColumn Width="120" Header="姓名" Binding="{Binding Name}"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>

<StackPanel Orientation="Horizontal" Grid.Row="1">
<Button Content="Add One Column" x:Name="AddColumnButton" Click="AddColumnButton_Click"/>
<Button Margin="10,0" Content="Delete One Column" x:Name="DeleteColumnButton" Click="DeleteColumnButton_Click"/>
</StackPanel>
</Grid>
</UserControl>


4. 后台代码,指定当前XAML的Datacontext是ViewModel。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SelectAllAndOrder.ViewModels;

namespace SelectAllAndOrder
{
public partial class MainPage : UserControl
{
private SelectAllViewModel _dataContext;
public MainPage()
{
InitializeComponent();
//this.Loaded += (s, e) =>
//    {
//        this.DataContext = _dataContext = new SelectAllViewModel();
//    };
//上面注释的代码等同于:
_dataContext = new SelectAllViewModel();
this.DataContext = _dataContext;
}

private void AddColumnButton_Click(object sender, RoutedEventArgs e)
{
_dataContext.AddUser();
}

private void DeleteColumnButton_Click(object sender, RoutedEventArgs e)
{
_dataContext.DeleteUser();
}
}
}


源代码: http://download.csdn.net/detail/eric_k1m/6020941
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: