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

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

制作一个表头为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;
            }
        }




你可能感兴趣的:(WPF,CheckBox,DataGrid,C#)