选择datagrid标头中的所有复选框及其在wpf mvvm中的绑定 [英] select all checkbox in header of datagrid and its binding in wpf mvvm

查看:64
本文介绍了选择datagrid标头中的所有复选框及其在wpf mvvm中的绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究wpf(mvvm体系结构)。我正在使用datagrid列出复选框,并在标题中单击了全选复选框,单击该复选框后,我希望选中所有复选框,反之亦然。请帮忙。

I am working on wpf (mvvm architecture). A am using datagrid to list the checkboxes and a SELECT ALL checkbox in the header on click of which I want all the checkboxes to be checked and vice-versa.Please help.

我在这里给出代码说明...
这是View.xaml

I am giving my code description here... This is the View.xaml

<DataGridCheckBoxColumn Binding="{Binding IsSelected}" Width="50" >
    <DataGridCheckBoxColumn.HeaderTemplate>
        <DataTemplate x:Name="dtAllChkBx">
            <CheckBox Name="cbxAll" Content="All" IsChecked="{Binding Path=DataContext.AllSelected,RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
        </DataTemplate>
    </DataGridCheckBoxColumn.HeaderTemplate>
</DataGridCheckBoxColumn>
<DataGridTemplateColumn Header="Name" Width="SizeToCells" IsReadOnly="True">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding UsecaseName}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>             

下面是viewmodel类

The below is the viewmodel class

private bool _IsSelected;
public bool IsSelected
{
    get { return _IsSelected; }
    set
    {
        _IsSelected = value;
        OnPropertyChanged("IsSelected");
    }
}

private bool _AllSelected;
public bool AllSelected
{
    get { return _AllSelected; }
    set
    {
        _AllSelected = value;
        foreach (var reportListItemModel in UsecaseListItems)
        {
            reportListItemModel.IsSelected = this._AllSelected;
        }
        OnPropertyChanged("IsSelected");

    }
}   

private ObservableCollection<UseCase> _usecaseListItems = new ObservableCollection<UseCase>();
public ObservableCollection<UseCase> UsecaseListItems
{
    get { return _usecaseListItems; }
    set {
        _usecaseListItems = value;
        OnPropertyChanged("UsecaseListItems");
    }
}

公共类UseCase:BaseNotifyPropertyChanged
{
公共字符串UsecaseName {get;组; }

public class UseCase: BaseNotifyPropertyChanged { public string UsecaseName { get; set; }

    public bool IsSelected { get; set; }

}

还应该做​​些什么,以便全选框正常工作?

What else should be done so that the select all check box works properly??

推荐答案

虽然存在许多解决方案,但我想打一个我经常遇到的特定问题说明,类似于:
在WPF数据网格中,通过MVVM方法进行绑定,

Though many solutions exist, but I want to hit a particular problem statement that I come across frequently, that is similar to: In a WPF DataGrid, bind through MVVM approach,


  1. 如果我选中全选复选框,则标头,则应选中该列中的所有复选框。

  2. 如果我取消选中标题中的全选复选框,则该列中的所有复选框都应取消选中

  3. 如果我取消选中任何复选框在任一行的该列中,则应取消选中标题中的全选复选框。

  4. 如果选中了该列中的所有复选框(每行一个),则选择标头中的所有复选框都应选中(留给您探索;))

  1. If I check "Select All" checkbox in the header, all the checkboxes in that column should be checked.
  2. If I uncheck "Select All" checkbox in the header, all the checkboxes in that column should be unchecked
  3. If I uncheck any of the checkbox in that column of any row, then the "Select All" checkbox in the header should be unchecked.
  4. If all checkboxes in that column are checked(one each row), then the "Select All" checkbox in the header should be checked (left to your exploration ;))

型号:

public class Employee : INotifyPropertyChanged
{
        private int _id;
        private string _name;
        private double _salary;
        private bool _isSelected;

        public int Id { get => _id; set => _id = value; }
        public string Name { get => _name; set => _name = value; }
        public double Salary { get => _salary; set => _salary = value; }
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                _isSelected = value;
                OnPropertyChanged(nameof(IsSelected));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }
}

ViewModel:

ViewModel:

public class EmployeeDetailsViewModel
{
        public EmployeeDetailsViewModel()
        {
            SelectAllCommand = new DelegateCommand<bool?>(HandleSelectAllCommand);
        }

        ObservableCollection<Employee> _employees = null;
        /// <summary>
        /// Collection bound to DataGrid
        /// </summary>
        public ObservableCollection<Employee> Employees { get => _employees; set { _employees = value; } }

        /// <summary>
        /// Command bound to SelectAll checkbox in XAML
        /// </summary>
        public ICommand SelectAllCommand { get; set; }

        private void HandleSelectAllCommand(bool? isChecked)
        {
            if (isChecked.HasValue)
            {
                foreach (var employee in Employees)
                {
                    employee.IsSelected = isChecked.Value;
                }
            }
        }

        void PrepareData()
        {
            this.Employees = new ObservableCollection<Employee>()
            {
                new Employee{Id=1, Name="abc", Salary=100000.00d},
                new Employee{Id=2, Name="def", Salary=200000.00d},
                new Employee{Id=3, Name="ghi", Salary=300000.00d},
                new Employee{Id=4, Name="jkl", Salary=400000.00d}
            };
        }
}

View(XAML):

View(XAML):

<DataGrid ItemsSource="{Binding Employees}" AutoGenerateColumns="False" CanUserAddRows="False" >
        <DataGrid.Columns>
            <DataGridTemplateColumn >
                <DataGridTemplateColumn.Header>
                    <CheckBox x:Name="chkSelectAll">
                        <i:Interaction.Triggers>
                            <i:EventTrigger  EventName="Click">
                                <i:InvokeCommandAction Command="{Binding Path = DataContext.SelectAllCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid,AncestorLevel=1}}" 
                                                       CommandParameter="{Binding ElementName=chkSelectAll, Path=IsChecked, UpdateSourceTrigger=PropertyChanged}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </CheckBox>
                </DataGridTemplateColumn.Header>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                            <i:Interaction.Triggers>
                                <i:EventTrigger  EventName="Unchecked">
                                    <local:EventTriggerPropertySetAction TargetObject="{Binding ElementName=chkSelectAll}" PropertyName="IsChecked" PropertyValue="False"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </CheckBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>

            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Id}" Header="Id"/>
            <DataGridTextColumn Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Header="Name"/>
            <DataGridTextColumn Binding="{Binding Salary, UpdateSourceTrigger=PropertyChanged}" Header="Salary"/>
        </DataGrid.Columns>
</DataGrid>

要访问交互触发器,您需要在Window / UserControl标记标签中添加以下名称空间:

To access the interaction triggers, you need to add following name space to Window/UserControl markup tags:

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
....
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">

简化的重要部分是由于< local:SetPropertyAction .. 。基于此SO答案此SO答案

The important part of simplification is due to <local:SetPropertyAction ... based on this SO answer or this SO answer.

当您访问这些链接时,别忘了投票和鼓励;)

Don't forget to up-vote and encourage, when you visit those link ;)

希望如此帮助一些人!

这篇关于选择datagrid标头中的所有复选框及其在wpf mvvm中的绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆