您的位置:首页 > 其它

WPF DataGrid表头Checkbox 全选与全反选

2017-06-24 08:48 323 查看
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);
}


        然后使
4000
用就非常方便了,比如如果要全选的话,一句话就搞定了
        
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>
     这样就能实现全选全反选,并能实现数据的绑定了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: