WPF Datagrid Header数据绑定,表头复选框实现全选、全否、部分选中,根据条目动态变化

4 篇文章 0 订阅
3 篇文章 0 订阅


制作一个表头为CheckBox可全选、全不选的列表,且可根据条目自动调整CheckBox的状态(选中、不选、部分选中)。

本来是想用DataGrid做一个CheckBox的列用于勾选其中的某些行,当时做出来之后想着添加一个全选、全否的功能。做两个按钮觉得太丑,就想着在标题栏做一个CheckBox实现此功能。开始不用会用模板,网上查了些资料可以用以下方式实现:

1、通过DatGridTemplateColumn修改表头模板实现

                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderTemplate>
                        <DataTemplate>
                            <CheckBox x:Name="CkB1" Click="Button_Click_2_Header" Tag="{Binding A4, Mode=TwoWay}" IsThreeState="True"></CheckBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.HeaderTemplate>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding A4, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Click="Button_Click_2_Body"></CheckBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
2、根据DataGridCheckBoxColumn修改表头模板实现
                <DataGridCheckBoxColumn >
                    <DataGridCheckBoxColumn.HeaderTemplate >
                        <DataTemplate>
                            <CheckBox Click="CheckBox_Click_3_Header"></CheckBox>
                        </DataTemplate>
                    </DataGridCheckBoxColumn.HeaderTemplate>

                    <DataGridCheckBoxColumn.ElementStyle>
                        <Style TargetType="CheckBox">
                            <Setter Property="IsChecked" Value="{Binding A5}"></Setter>
                        </Style>
                    </DataGridCheckBoxColumn.ElementStyle>
                </DataGridCheckBoxColumn>

实现显示之后可根据Click、Checked、UnCkecked事件控制全选与全否。

但是如何实现表头状态的自动调整没啥思路,网上搜了一下资料:

以下两种实现方式:

1、给表头控件添加空间名称,使用时根据名称找到控件,再根据动作调整控件状态。

如查找“CKB1“控件,通过VisualTreeHelper

        CheckBox cb = GetVisualChild<CheckBox>(this.TestDG, v => v.Name == "CkB1");
        public T GetVisualChild<T>(DependencyObject parent, Func<T, bool> 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<T>(v, predicate);
                    if (child != null)
                    {
                        return child;
                    }
                }
                else
                {
                    if (predicate(child))
                    {
                        return child;
                    }
                }
            }
            return null;
        }

2、直接绑定数据,网上没找到源码,分享一下其中一种实现形式:

a,使用DataGridCheckBoxColumn

<DataGridCheckBoxColumn>
                    <DataGridCheckBoxColumn.HeaderTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=DataContext.IsSelectedAll,Mode=TwoWay,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, UpdateSourceTrigger=PropertyChanged}"
                                      Click="DGHeaderCheckBoxClick"
                                      IsThreeState="True"></CheckBox>
                        </DataTemplate>
                    </DataGridCheckBoxColumn.HeaderTemplate>
                    <DataGridCheckBoxColumn.ElementStyle>
                        <Style TargetType="CheckBox">
                            <Setter Property="IsChecked" Value="{Binding A5,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></Setter>
                            <EventSetter Event="CheckBox.Click" Handler="DGRowCheckBoxClick"></EventSetter>
                        </Style>
                    </DataGridCheckBoxColumn.ElementStyle>
                </DataGridCheckBoxColumn>

b、使用DataGridTemplateColumn

<DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=DataContext.IsSelectedAll,Mode=TwoWay,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, UpdateSourceTrigger=PropertyChanged}"
                                      Click="DGHeaderCheckBoxClick"
                                      IsThreeState="True"></CheckBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.HeaderTemplate>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding A5,Mode=TwoWay,  UpdateSourceTrigger=PropertyChanged}" Click="DGRowCheckBoxClick"></CheckBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </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<Data> Datas1
        {
            get { return (ObservableCollection<Data>)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<Data>), 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<Data>()
            {
                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;
            }
        }




  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现全选复选框的列表控件,可以使用WPF中的ListView控件和GridViewColumnHeader控件来实现。 首先,在ListView中添加一个CheckBox列作为全选复选框,可以使用GridViewColumnHeader控件来实现。在该控件的Click事件中,可以遍历ListView中的所有数据项,并将其对应的CheckBox控件的IsChecked属性设置为GridViewColumnHeader的IsChecked属性值。 以下是一个简单的示例代码: ```xml <ListView> <ListView.View> <GridView> <GridViewColumn> <GridViewColumnHeader Click="GridViewColumnHeader_Click"> <CheckBox x:Name="chkSelectAll" /> </GridViewColumnHeader> </GridViewColumn> <GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Age}" /> <GridViewColumn Header="性别" DisplayMemberBinding="{Binding Gender}" /> </GridView> </ListView.View> </ListView> ``` ```csharp private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e) { foreach (var item in listView.Items) { var container = listView.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem; var checkBox = FindVisualChild<CheckBox>(container); checkBox.IsChecked = chkSelectAll.IsChecked; } } private T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject { if (obj != null) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { var child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is T) return (T)child; var childOfChild = FindVisualChild<T>(child); if (childOfChild != null) return childOfChild; } } return null; } ``` 在上面的示例代码中,FindVisualChild方法用于查找ListViewItem中的CheckBox控件。可以将该方法封装成一个扩展方法,以便在其他地方重复使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值