如何在WPF DataGrid中通过DataGrid标头CheckBox选择列的所有复选框

我有一个带有一个CheckBoxColumn的DataGrid。 在CheckBoxColumn的标题中,我添加了一个CheckBox来选择该Datagrid Row的所有CheckBox。

我怎样才能做到这一点?

我的WPF dataGrid的XAML代码:

                 

将候选类转换为以下内容:

 public class Candidate : DependencyObject { //CandidateID Dependency Property public int CandidateID { get { return (int)GetValue(CandidateIDProperty); } set { SetValue(CandidateIDProperty, value); } } public static readonly DependencyProperty CandidateIDProperty = DependencyProperty.Register("CandidateID", typeof(int), typeof(Candidate), new UIPropertyMetadata(0)); //RegisterNo Dependency Property public int RegisterNo { get { return (int)GetValue(RegisterNoProperty); } set { SetValue(RegisterNoProperty, value); } } public static readonly DependencyProperty RegisterNoProperty = DependencyProperty.Register("RegisterNo", typeof(int), typeof(Candidate), new UIPropertyMetadata(0)); //CandidateName Dependency Property public string CandidateName { get { return (string)GetValue(CandidateNameProperty); } set { SetValue(CandidateNameProperty, value); } } public static readonly DependencyProperty CandidateNameProperty = DependencyProperty.Register("CandidateName", typeof(string), typeof(Candidate), new UIPropertyMetadata("")); //BooleanFlag Dependency Property public bool BooleanFlag { get { return (bool)GetValue(BooleanFlagProperty); } set { SetValue(BooleanFlagProperty, value); } } public static readonly DependencyProperty BooleanFlagProperty = DependencyProperty.Register("BooleanFlag", typeof(bool), typeof(Candidate), new UIPropertyMetadata(false)); } 

在MainWindow.xaml中:

                  

在MainWindow.xaml.cs中:

  public MainWindow() { DataContext = this; CandidateList.Add(new Candidate() { CandidateID = 1, CandidateName = "Jack", RegisterNo = 123, BooleanFlag = true }); CandidateList.Add(new Candidate() { CandidateID = 2, CandidateName = "Jim", RegisterNo = 234, BooleanFlag = false }); InitializeComponent(); } //List Observable Collection private ObservableCollection _candidateList = new ObservableCollection(); public ObservableCollection CandidateList { get { return _candidateList; } } private void CheckBox_Checked(object sender, RoutedEventArgs e) { foreach (var item in CandidateList) { item.BooleanFlag = true; } } private void UnheckBox_Checked(object sender, RoutedEventArgs e) { foreach (var item in CandidateList) { item.BooleanFlag = false; } } 

严格地说,模型不应该知道视图,因此blindmeis提出的解决方案,其中模型更改正在更新数据网格中的每一行,打破了MVVM / Presentation Design模式。 请记住,在MVVM中,依赖流是View – > ViewModel – > Model,因此如果您在视图模型中引用控件(或控制代码隐藏),那么您已经有效地破坏了模式,并且您可能会遇到问题。

我已添加CheckBox以选择Datagrid Row中的所有CheckBox

如果你的意思是选择datagrid 列中的所有复选框,那么我会说:只需用checked / unchecked更新你的itemssource集合。

 public bool SelectAll { get{return this._selectAll;} set { this._selectAll = value; this.MyItemsSourceCollection.ForEach(x=>x.MyRowCheckProperty=value); this.OnPropertyChanged("SelectAll"); } } 

XAML

            

我不知道如果xaml绑定是正确的,但我希望你能看到我的意图

事实certificate,这比人们希望的要难得多。

第一个问题是您不能将视图模型绑定到列标题,因为它没有视图模型作为其数据上下文,因此您需要绑定代理才能正确地将绑定路由到视图模型。

 public class BindingProxy : Freezable { public static readonly DependencyProperty DataProperty = DependencyProperty.Register( "Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); public object Data { get { return this.GetValue(DataProperty); } set { this.SetValue(DataProperty, value); } } protected override Freezable CreateInstanceCore() { return new BindingProxy(); } } 

现在在数据网格的资源中创建一个绑定代理:

    

然后该列需要定义为:

             

请注意,需要绑定到复选框的IsChecked依赖项属性及其Command属性,并且IsChecked绑定是OneWayIsChecked绑定获取复选框以显示项目的当前状态, Command绑定执行批量选择。 你需要两者。

现在在视图模型中:

 public bool? AreAllSelected { get { return this.Items.All(candidate => candidate.IsSelected) ? true : this.Items.All(candidate => !candidate.IsSelected) ? (bool?)false : null; } set { if (value != null) { foreach (var item in this.Items) { item.IsSelected = value.Value; } } this.RaisePropertyChanged(); } } 

SelectAllCommand属性是ICommand一个实现,其中Execute方法是:

 public void Execute(object parameter) { var allSelected = this.AreAllSelected; switch (allSelected) { case true: this.AreAllSelected = false; break; case false: case null: this.AreAllSelected = true; break; } } 

最后,每次IsSelected的值发生变化时,行项目视图模型(即Items )都需要在主视图模型上引发PropertyChanged 。 你是怎么做到的,这取决于你。