在项目中,凡是涉及到表格的地方用的最多的控件,自然少不了DataGrid的身影,它明了的展示各种数据让人十分喜欢。现在要实现一个功能,使DataGrid具有全选和项选中的功能,如果在传统后台代码中完成这个事情可以说十分简单,但是换到MVVM模式下呢? 不得不面临一个很囧的情况,为了完成UI端CheckBox被选中后能在ViewModel中获取到选中的数据,不得不在在业务实体之外添加一个字段IsChecked 来与我们的数据交互,这样不仅影响美观还影响心情。

  为了实现这一点,无疑需要设置DataGridTemplateColumn的CellTemplate,同时让每一个checkBox拥有这条数据的上下文引用,已方便在当我们选中或反选时能确定数据项,最好的设置时机当然是DataGrid的LoadingRow事件,可以捕获到我们所需要的一切。

  当然,为了实现MVVM,我们需要添加一下附加属性

 public static ObservableCollection<object> GetSelectedObjects(DependencyObject obj)
{
return (ObservableCollection<object>)obj.GetValue(SelectedObjectsProperty);
} public static void SetSelectedObjects(DependencyObject obj, ObservableCollection<object> value)
{
obj.SetValue(SelectedObjectsProperty, value);
}
      
// 用于通知到ViewModel已经被选中的列
public static readonly DependencyProperty SelectedObjectsProperty =
DependencyProperty.RegisterAttached("SelectedObjects", typeof(ObservableCollection<object>), typeof(DataGrid), new PropertyMetadata(new ObservableCollection<object>())); public static bool GetMonitor(DependencyObject obj)
{
return (bool)obj.GetValue(MonitorProperty);
} public static void SetMonitor(DependencyObject obj, bool value)
{
obj.SetValue(MonitorProperty, value);
} // 监视器,用于在DataGrid初始化的时候能有时机注册LoadingRow事件
public static readonly DependencyProperty MonitorProperty =
DependencyProperty.RegisterAttached("Monitor", typeof(bool), typeof(DataGrid), new PropertyMetadata(false, OnMonitorStateChanged)); private static void OnMonitorStateChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
var attachedDataGrid = dp as DataGrid;
_attachedDataGrid = attachedDataGrid;
_attachedDataGrid.LoadingRow += (s, ee) =>
{
object dataContext = ee.Row.DataContext;
var elementControl = _attachedDataGrid.Columns[] as DataGridSelectableColumn;
if (elementControl == null)
throw new InvalidCastException("请将DataGridSelectableColumn放在DataGrid的第一列");
FrameworkElement element = elementControl.GetCellContent(ee.Row); var elementContext = new SelectableColumnObject() {RowDataContext = new WeakReference( dataContext) };
           //当CheckBox的IsChecked属性值变化之后发生
elementContext.OnChildItemStateChanged += elementContext_OnChildItemStateChanged;
element.DataContext = elementContext; };
} static void elementContext_OnChildItemStateChanged(WeakReference rowDataContext, bool obj)
{
_currentColumn.UpdateChildItemSelectedState(rowDataContext, obj);
}

  我将这一列的数据上下文保存到了一个名为RowDataContext的字段中,这样就满足了当选择状态更新时我能知道是那条数据,那么剩下的工作就是列选择和全选状态更新的事件了。Silverlight中DataGrid没有HeaderTemplate,也没有其他事件能够帮助我知道Header的加载,这时候需要借助于xaml,如下

     <sdk:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="sdk:DataGridColumnHeader">
<Setter Property="Padding" Value="" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGridColumnHeader">
<CheckBox VerticalAlignment="Center" HorizontalAlignment="Center" VerticalContentAlignment="Center" Content="全选" Loaded="OnHeaderCheckBoxLoaded" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridTemplateColumn.HeaderStyle>

  有了这里我们就可以直接在后台代码中定义事件进行处理

 private void OnHeaderCheckBoxLoaded(object sender, RoutedEventArgs e)
{
var checkBox = sender as CheckBox;
if (checkBox == null)
return; checkBox.Loaded -= this.OnHeaderCheckBoxLoaded;
checkBox.Checked += (s2, e2) => this.UpdateAllItemSelectedState(true);
checkBox.Unchecked += (s2, e2) => this.UpdateAllItemSelectedState(false);
}

  到此为止,我们要做的工作基本已经完工,全选状态、行数据的选择状态更新我们做相应处理了。

源码下载:Silverlight下MVVM全选控件_无需额外添加字段.zip

Silverlight中在MVVM模式下对DatagridRow选择控件封装的更多相关文章

  1. Atitit.ui控件---下拉菜单选择控件的实现select html

    Atitit.ui控件---下拉菜单选择控件的实现select   html 1. 调用& model的实现 1 2. -----select.jsp------ 1 1. 调用& m ...

  2. WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题

    问题:WPF中MVVM模式下 ListView绑定ListCollectionView时,CurrentChanged无法触发 解决方案: 初期方案:利用ListView的SelectionChang ...

  3. 关于使用MVVM模式在WPF的DataGrid控件中实现ComboBox编辑列

    最近在做一个组态软件的项目,有一个需求需要在建立IO设备变量的时候选择变量的类型等. 建立IO变量的界面是一个DataGrid实现的,可以一行一行的新建变量,如下如所示: 这里需要使用带有ComboB ...

  4. angular中的MVVM模式

    在开始介绍angular原理之前,我们有必要先了解下mvvm模式在angular中运用.虽然在angular社区一直将angular统称为前端MVC框架,同时angular团队也称它为MVW(What ...

  5. Silverlight中使用MVVM(1)--基础

    Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...

  6. Silverlight中使用MVVM(3)

    Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...

  7. Silverlight中使用MVVM(1)

    Silverlight中使用MVVM(1)   Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 ...

  8. MVVM模式下弹出窗体

    原地址:http://www.cnblogs.com/yk250/p/5773425.html 在mvvm模式下弹出窗体,有使用接口模式传入参数new一个对象的,还有的是继承于一个window,然后在 ...

  9. js架构设计模式——MVVM模式下,ViewModel和View,Model有什么区别

    MVVM模式下,ViewModel和View,Model有什么区别 Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就 ...

随机推荐

  1. 利用xshell从windows上传文件到虚拟机

    Xshell实现Windows上传文件到Linux主机 经常有这样的需求,我们在Windows下载的软件包,如何上传到远程Linux主机上?还有如何从Linux主机下载软件包到Windows下:之前我 ...

  2. tomcat install on Linux

    1)下载apache-tomcat-6.0.10.tar.gz 2)#tar -zxvf apache-tomcat-6.0.10.tar.gz ://解压 3)#cp -R apache-tomca ...

  3. Araxis Merge Professional v2014.4565 特别版 | 文件比较合并

    http://www.ttrar.com/html/AraxisMerge.html Araxis Merge 是一个可视化的文件比较.合并和同步的软件,能够方便的被软件工程师和 web 站点开发者使 ...

  4. LeetCode——Remove Element

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  5. [D3] 12. Basic Transitions with D3

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. 字符串匹配算法-BM

    在用于查找子字符串的算法中,BM(Boyer-Moore)算法是当前有效且应用比较广泛的一种算法,各种文本编辑器的“查找”功能(Ctrl+F),大多采用Boyer-Moore算法.比我们学习的KMP算 ...

  7. 关于Clone 的方法使用

    package cn.hncu.day7.clone.v1;//克隆的套路:// 第1步:重写User类的clone()方法,以供外面调用.因为外面的类无法直接调用User类父类中的clone()方法 ...

  8. git 远程追踪

    $ git branch --set-upstream-to origin/master http://stackoverflow.com/questions/21729560/how-to-make ...

  9. CentOS6.5编译安装最新MySQL 5.7.11

    安装前工作:1,从官方网址下载MySQL5.7.11源码包,大概49M2,安装好CentOS6.5 64位操作系统.建议update操作系统,以便是此版本最新的3. yum -y install  g ...

  10. 使用passenger在Centos7部署Puma+Nginx+Ruby on Rails

    安装ruby环境 RVM(ruby版本管理工具)安装 gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A170311 ...