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

来源:互联网 发布:淘宝上没有京东 编辑:程序博客网 时间:2024/05/29 14:18

实现一个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

原创粉丝点击