WPF 在使用DataGrid展示数据的时候经常会使用到checkbox列,特别是id列
例如下面这种效果:
WPF 要实现DataGrid checkbox全选与全反选,方法有几种
方法一:使用DataGridTemplateColumn自定义模板
先用模板把前台布局好
<DataGridTemplateColumn Header="选择" >
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Click="CheckBox_Click_3" ></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox VerticalAlignment="Center" Loaded="CheckBox_Loaded_1" Tag="{Binding Id}" Click="CheckBox_Click_1" HorizontalAlignment="Center"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
用模板的方式虽然灵活,但是不好获取到里边的控件,比如这里的checkbox
直接获取是不行的
private void CheckBox_Click_3(object sender, RoutedEventArgs e)
{
CheckBox headercb = (CheckBox)sender;
for (int i = 0; i < mydg.Items.Count; i++)
{
//获取行
DataGridRow neddrow = (DataGridRow)mydg.ItemContainerGenerator.ContainerFromIndex(i);
//获取该行的某列
CheckBox cb = (CheckBox)mydg.Columns[0].GetCellContent(neddrow);
cb.IsChecked = headercb.IsChecked;
}
}
因为不是直接用的DataGridCheckBoxColumn,获取到的不是直接的checkbox
如果要获取可以使用树递归来获取
//获取并选中DependencyObject中的CheckBox
public void GetVisualChild(DependencyObject parent)
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
DependencyObject v = (DependencyObject)VisualTreeHelper.GetChild(parent, i);
CheckBox child = v as CheckBox;
if (child == null)
{
GetVisualChild(v);
}
else
{
child.IsChecked = true;
return ;
}
}
}
private void CheckBox_Click_3(object sender, RoutedEventArgs e)
{
GetVisualChild(mydg);
}
但是直接这样他是把所有的checkbox都选中了的,包括其他列的,而且由于遍历datagrid所有的行列,效率很低
我们可以找到需要的列在调用该方法 , 就可以不用遍历整个datagrid了,而且可以一次找到
private void CheckBox_Click_3(object sender, RoutedEventArgs e)
{
for (int i = 0; i < mydg.Items.Count; i++)
{
//获取行
DataGridRow neddrow = (DataGridRow)mydg.ItemContainerGenerator.ContainerFromIndex(i);
//获取该行的某列
var cb = mydg.Columns[0].GetCellContent(neddrow);
//获取到需要的列之后在去获取需要的控件
GetVisualChild(cb);
}
}
方法二:在控件的加载事件里边把控件缓存下来再用
List<CheckBox> headerChecks = new List<CheckBox>();
/// <summary>
/// 由于不是太好获取就把控件先放到内存中缓存下来
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckBox_Loaded_1(object sender, RoutedEventArgs e)
{
CheckBox cbtemp = (CheckBox)sender;
headerChecks.Add(cbtemp);
}
然后使用就非常方便了,比如如果要全选的话,一句话就搞定了
private void CheckBox_Click_3(object sender, RoutedEventArgs e)
{
headerChecks.ForEach(a=>a.IsChecked=true);
}
方法三:使用DataGridCheckBoxColumn
使用DataGridCheckBoxColumn只需要获取到第1列的内容就可以直接转化成chekbox了,然后操作就行了
前台:
<DataGridCheckBoxColumn >
<DataGridCheckBoxColumn.HeaderTemplate >
<DataTemplate>
<CheckBox Click="CheckBox_Click_2" HorizontalAlignment="Center" VerticalAlignment="Center" Tag="{Binding Id}"></CheckBox>
</DataTemplate>
</DataGridCheckBoxColumn.HeaderTemplate>
<DataGridCheckBoxColumn.CellStyle >
<Style >
<Setter Property="CheckBox.VerticalAlignment" Value="Center"></Setter>
<Setter Property="CheckBox.HorizontalAlignment" Value="Center"></Setter>
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
后台:
private void CheckBox_Click_2(object sender, RoutedEventArgs e)
{
CheckBox headercb = (CheckBox)sender;
for (int i = 0; i < mydg.Items.Count; i++)
{
//获取行
DataGridRow neddrow = (DataGridRow)mydg.ItemContainerGenerator.ContainerFromIndex(i);
//获取该行的某列
CheckBox cb = (CheckBox)mydg.Columns[0].GetCellContent(neddrow);
cb.IsChecked = headercb.IsChecked;
}
}
但是使用DataGridCheckBoxColumn如何绑定数据又成了一个问题
为DataGridCheckBoxColumn绑定数据和设置一点简单的样式
<DataGridCheckBoxColumn >
<DataGridCheckBoxColumn.HeaderTemplate >
<DataTemplate>
<CheckBox Click="CheckBox_Click_2" HorizontalAlignment="Center" VerticalAlignment="Center" Tag="{Binding Id}"></CheckBox>
</DataTemplate>
</DataGridCheckBoxColumn.HeaderTemplate>
<!--为该列的CheckBox Tag属性绑定值-->
<DataGridCheckBoxColumn.ElementStyle>
<Style TargetType="CheckBox">
<Setter Property="Tag" Value="{Binding Id}"></Setter>
</Style>
</DataGridCheckBoxColumn.ElementStyle>
<!--设置一点样式-->
<DataGridCheckBoxColumn.CellStyle >
<Style >
<Setter Property="CheckBox.VerticalAlignment" Value="Center"></Setter>
<Setter Property="CheckBox.HorizontalAlignment" Value="Center"></Setter>
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
这样就能实现全选全反选,并能实现数据的绑定了