Silverlight中在MVVM模式下对DatagridRow选择控件封装
2014-05-16 15:22
246 查看
在项目中,凡是涉及到表格的地方用的最多的控件,自然少不了DataGrid的身影,它明了的展示各种数据让人十分喜欢。现在要实现一个功能,使DataGrid具有全选和项选中的功能,如果在传统后台代码中完成这个事情可以说十分简单,但是换到MVVM模式下呢? 不得不面临一个很囧的情况,为了完成UI端CheckBox被选中后能在ViewModel中获取到选中的数据,不得不在在业务实体之外添加一个字段IsChecked 来与我们的数据交互,这样不仅影响美观还影响心情。
为了实现这一点,无疑需要设置DataGridTemplateColumn的CellTemplate,同时让每一个checkBox拥有这条数据的上下文引用,已方便在当我们选中或反选时能确定数据项,最好的设置时机当然是DataGrid的LoadingRow事件,可以捕获到我们所需要的一切。
当然,为了实现MVVM,我们需要添加一下附加属性
我将这一列的数据上下文保存到了一个名为RowDataContext的字段中,这样就满足了当选择状态更新时我能知道是那条数据,那么剩下的工作就是列选择和全选状态更新的事件了。Silverlight中DataGrid没有HeaderTemplate,也没有其他事件能够帮助我知道Header的加载,这时候需要借助于xaml,如下
有了这里我们就可以直接在后台代码中定义事件进行处理
到此为止,我们要做的工作基本已经完工,全选状态、行数据的选择状态更新我们做相应处理了。
源码下载:Silverlight下MVVM全选控件_无需额外添加字段.zip
为了实现这一点,无疑需要设置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[0] 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="4" /> <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 2系列(8):使用样式封装控件观感
- 一步一步学Silverlight 2系列(8):使用样式封装控件观感
- Silverlight 学习笔记——MVVM模式实现主从数据显示 ---转
- Silverlight MMORPG网页游戏开发课程[一期] 第三课:封装游戏控件
- WPF/Silverlight中的MVVM模式能否在WinForm/ASP.NET上运用?
- 使用 ASP.NET 控件封装 Silverlight
- Silverlight 使用样式封装控件观感
- Silverlight 按钮类控件和选择控件 示例
- Silverlight 按钮类控件和选择控件 示例
- Silverlight MMORPG网页游戏开发课程[一期] 第三课:封装游戏控件
- 一步一步学Silverlight 2系列(8):使用样式封装控件观感
- [Silverlight]使用MVVM模式打造英汉词典
- 带时间模式的日期选择控件(修改版)
- Silverlight 按钮类控件和选择控件 示例
- (8):Silverlight 2 使用样式封装控件观感
- 一步一步学Silverlight 2系列(8):使用样式封装控件观感
- 一步一步学Silverlight 2系列(8):使用样式封装控件观感
- WPF控件的MVVM模式
- Silverlight 4 RIA Service dataform Template, 代码选择控件,Validate验证使用技巧
- WPF/Silverlight中的MVVM模式能否在WinForm/ASP.NET上运用?