制作一个表头为CheckBox可全选、全不选的列表,且可根据条目自动调整CheckBox的状态(选中、不选、部分选中)。
本来是想用DataGrid做一个CheckBox的列用于勾选其中的某些行,当时做出来之后想着添加一个全选、全否的功能。做两个按钮觉得太丑,就想着在标题栏做一个CheckBox实现此功能。开始不用会用模板,网上查了些资料可以用以下方式实现:
1、通过DatGridTemplateColumn修改表头模板实现
2、根据DataGridCheckBoxColumn修改表头模板实现
实现显示之后可根据Click、Checked、UnCkecked事件控制全选与全否。
但是如何实现表头状态的自动调整没啥思路,网上搜了一下资料:
以下两种实现方式:
1、给表头控件添加空间名称,使用时根据名称找到控件,再根据动作调整控件状态。
如查找“CKB1“控件,通过VisualTreeHelper
CheckBox cb = GetVisualChild(this.TestDG, v => v.Name == "CkB1");
public T GetVisualChild(DependencyObject parent, Func predicate) where T : Visual
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
DependencyObject v = (DependencyObject)VisualTreeHelper.GetChild(parent, i);
T child = v as T;
if (child == null)
{
child = GetVisualChild(v, predicate);
if (child != null)
{
return child;
}
}
else
{
if (predicate(child))
{
return child;
}
}
}
return null;
}
2、直接绑定数据,网上没找到源码,分享一下其中一种实现形式:
a,使用DataGridCheckBoxColumn
b、使用DataGridTemplateColumn
绑定的类
public class DataT : DependencyObject
{
public bool? IsSelectedAll
{
get { return ( bool?)GetValue(IsSelectedAllProperty); }
set { SetValue(IsSelectedAllProperty, value); }
}
// Using a DependencyProperty as the backing store for IsSelectedAll. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsSelectedAllProperty =
DependencyProperty.Register("IsSelectedAll", typeof( bool?), typeof(DataT));
public string Name2
{
get { return (string)GetValue(Name2Property); }
set { SetValue(Name2Property, value); }
}
// Using a DependencyProperty as the backing store for Name2. This enables animation, styling, binding, etc...
public static readonly DependencyProperty Name2Property =
DependencyProperty.Register("Name2", typeof(string), typeof(DataT));
public ObservableCollection Datas1
{
get { return (ObservableCollection)GetValue(Datas1Property); }
set { SetValue(Datas1Property, value); }
}
// Using a DependencyProperty as the backing store for Datas1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty Datas1Property =
DependencyProperty.Register("Datas1", typeof(ObservableCollection), typeof(DataT));
}
public class Data : DependencyObject
{
。。。。。。
public bool A5
{
get { return (bool)GetValue(A5Property); }
set { SetValue(A5Property, value); }
}
// Using a DependencyProperty as the backing store for A5. This enables animation, styling, binding, etc...
public static readonly DependencyProperty A5Property =
DependencyProperty.Register("A5", typeof(bool), typeof(Data));
}
绑定方式
datat.Datas1 = new ObservableCollection()
{
new Data(){ A1 = "A1", A2 = true, A3 = "A3", A4 = false, A5 = true },
new Data(){ A1 = "A1", A2 = true, A3 = "A3", A4 = false, A5 = true }
};
datat.IsSelectedAll = true;
datat.Name2 = "ASD";
this.TestDG2.DataContext = datat;
点击表头和行对应的响应函数
private void DGHeaderCheckBoxClick(object sender, RoutedEventArgs e)
{
CheckBox cb = sender as CheckBox;
if (null != cb)
{
if (cb.IsChecked == true)
{
//全选
foreach (var item in datat.Datas1)
{
item.A5 = true;
}
}
if (cb.IsChecked == false)
{
//全选
foreach (var item in datat.Datas1)
{
item.A5 = false;
}
}
}
}
private void DGRowCheckBoxClick(object sender, RoutedEventArgs e)
{
if (datat.Datas1.FirstOrDefault(item => item.A5 == false) != null && datat.Datas1.FirstOrDefault(item => item.A5 == true) != null)
{
datat.IsSelectedAll = null;
}
else if (datat.Datas1.FirstOrDefault(item => item.A5 == false) == null)
{
datat.IsSelectedAll = true;
}
else
{
datat.IsSelectedAll = false;
}
}