如何在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
绑定是OneWay
。 IsChecked
绑定获取复选框以显示项目的当前状态, 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
。 你是怎么做到的,这取决于你。