在项目中,凡是涉及到表格的地方用的最多的控件,自然少不了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. oninput,onpropertychange,onchange的用法和区别

    1.前言 由于工作需要,需实现一个类似于微博输入框的功能,在用户动态输入文字的时候,修改提示“您还可以输入XX字”.如下图所示: 因此,稍微研究了一下oninput,onpropertychange, ...

  2. Http(3)

    响应行 1.常见的状态: 200:表示请求处理完美返回 302:表示请求需要经进一步细化 404:表示客户访问的资源找不到. 500: 表示服务器的资源发送错误.(服务器内部错误) 2.常见的响应头 ...

  3. 【转】android蓝牙开发 蓝牙设备的查找和连接

    1.  首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限 // 管理蓝牙设备的权限 <uses-permissionandroid:name="android. ...

  4. C#使用Sockets操作FTP【转载】

    using System; using System.Collections; using System.IO; using System.Net; using System.Net.Sockets; ...

  5. [Webpack 2] Tree shaking with Webpack 2

    The less code you can send to the browser, the better. The concept of tree shaking basically says th ...

  6. popupWindow使用详解

    popupWindow说起来简单,但是使用略麻烦,今天带大家来看看怎么使用,先来看看效果图: 先来看看布局文件吧: <RelativeLayout xmlns:android="htt ...

  7. MVC中HttpContext, HttpContextBase, HttpContextWrapper联系

    HttpContext // // 摘要: // 封装有关个别 HTTP 请求的所有 HTTP 特定的信息. public sealed class HttpContext : IServicePro ...

  8. 设计webapp的新思路

    一般设计移动应用有3中方式:原生.脚本.混合:今天我们用另一种方式实现. 我叫它:响应式网页webApp 一.具体构架思路是这样的: 客户端:Android手机 Android手机中有控件WebVie ...

  9. Sql Server 2008 还原数据库 3154错误

    sqlserver2008还原数据库时出现了3154错误,具体错误信息如下: 错误信息 The backup set holds a backup of a database other than t ...

  10. 重温sql语句中的join操作

    1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,RIGHT,一个表或视图也可以可以和它自身做JOIN操 ...