博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DataGrid中动态添加列,使用CheckBox选择行
阅读量:5142 次
发布时间:2019-06-13

本文共 3674 字,大约阅读时间需要 12 分钟。

在DataGrid中使用CheckBox选择行时典型的错误就是CheckBox没有Binding到任何属性上,这样的话当拖动滚动条时CheckBox.IsChecked就会乱掉,如Demo中左边那个DataGrid所示。最直观的解决方法是禁用DataGrid的滚动条,或者在绑定的数据上添加一个用于绑定CheckBox的bool属性。

其实只要在DataGrid.LoadingRow事件中将CheckBox的DataContext设定为另外一个Object,就不需要牺牲DataGrid的高效能,也不需要改变原有数据的结构。具体实现如下:

 

 

public class MyDataGrid : DataGrid     {
private const string HeaderCheckBoxName = "select_column_checkbox"; private Dictionary
_markObjects; private DataGridTemplateColumn _selectColumn; private CheckBox _selectCheckBox; public MyDataGrid() {
_markObjects = new Dictionary
(); _selectColumn = new DataGridTemplateColumn(); _selectColumn.HeaderStyle = GetHeaderStyle(); _selectColumn.CellTemplate = GetCellTemplate(); this.Columns.Insert(0, _selectColumn); this.SizeChanged += new SizeChangedEventHandler(OnSizeChanged); } public void SelectAll() {
if (_selectCheckBox != null) _selectCheckBox.IsChecked = true; SetAllSelectedStates(true); } public void UnselectAll() {
if (_selectCheckBox != null) _selectCheckBox.IsChecked = false; SetAllSelectedStates(false); } public List
GetSelectedItems
() {
List
result = new List
(); if (ItemsSource != null) { var enu = ItemsSource.GetEnumerator(); while (enu.MoveNext()) { if (GetMarkObject(enu.Current).Selected) result.Add((T)enu.Current); } } return result; } protected override void OnLoadingRow(DataGridRowEventArgs e) { base.OnLoadingRow(e); object dataContext = e.Row.DataContext; FrameworkElement element = _selectColumn.GetCellContent(e.Row); element.DataContext = GetMarkObject(dataContext); } private Style GetHeaderStyle() { Style style = new System.Windows.Style(); style.TargetType = typeof(ContentControl); StringBuilder tmp = new StringBuilder(); tmp.Append("
"); tmp.Append(string.Format("
", HeaderCheckBoxName)); tmp.Append("
"); DataTemplate contentTemplate = XamlReader.Load(tmp.ToString()) as DataTemplate; style.Setters.Add(new Setter(ContentControl.ContentTemplateProperty, contentTemplate)); return style; } private DataTemplate GetCellTemplate() { StringBuilder tmp = new StringBuilder(); tmp.Append("
"); tmp.Append("
"); tmp.Append("
"); return XamlReader.Load(tmp.ToString()) as DataTemplate; } private MarkObject GetMarkObject(Object obj) { if (_markObjects.ContainsKey(obj) == false) { MarkObject markObject; markObject = new MarkObject(); _markObjects.Add(obj, markObject); } return _markObjects[obj]; } private void OnSizeChanged(object sender, SizeChangedEventArgs e) { _selectCheckBox = this.GetChild
(HeaderCheckBoxName); if (_selectCheckBox == null) return; _selectCheckBox.Checked += (sender2, e2) => SetAllSelectedStates(true); _selectCheckBox.Unchecked += (sender2, e2) => SetAllSelectedStates(false); } private void SetAllSelectedStates(bool value) { if (ItemsSource == null) return; var enu = ItemsSource.GetEnumerator(); while (enu.MoveNext()) { GetMarkObject(enu.Current).Selected = value; } } }

其中MarkObject是一个继承INotifyPropertyChanged的类,包含Selected属性,这样更改Selected时可以更新UI。在构造函数中直接插入了个模板列,模板列使用XamlReader.Load(string str)方法直接在代码中创建模板。至于列头的CheckBox则在SizeChanged事件时才可以通过VisualTreeHelper.GetChild递归找到。

 

原文:上面有效果图,效果图怎么实现的

 

 

转载于:https://www.cnblogs.com/whpepsi/archive/2012/02/22/2363120.html

你可能感兴趣的文章
C#double转化成字符串 保留小数位数, 不以科学计数法的形式出现。
查看>>
利用IP地址查询接口来查询IP归属地
查看>>
构造者模式
查看>>
Hbuild在线云ios打包失败,提示BuildConfigure Failed 31013 App Store 图标 未找到 解决方法...
查看>>
找到树中指定id的所有父节点
查看>>
jQuery on(),live(),trigger()
查看>>
Date Picker控件:
查看>>
你的第一个Django程序
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>