我正在研究wpf(mvvm架构)。我正在使用datagrid列出复选框和单击标题中的SELECT ALL复选框,我希望检查所有复选框,反之亦然。请帮助。
我在这里给出了我的代码说明...... 这是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类
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");
}
}
public class UseCase:BaseNotifyPropertyChanged { public string UsecaseName {get;组; }
public bool IsSelected { get; set; }
}
还应该做什么,以便select all复选框正常工作?
答案 0 :(得分:1)
您的UseCase类必须实现 INotifyPropertyChanged 接口
public class UseCase : INotifyPropertyChanged
{
//...
private bool _isSelected;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
修改:这里我得到了一个效果良好的完整示例
* .xaml(查看)
<DataGrid x:Name="dataGrid" ItemsSource="{Binding MyCollection}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding IsSelected}" Width="50" >
<DataGridCheckBoxColumn.HeaderTemplate>
<DataTemplate x:Name="dtAllChkBx">
<CheckBox Name="cbxAll" DataContext="{Binding ElementName=dataGrid, Path=DataContext}" Command="{Binding MyCommand}" CommandParameter="{Binding Path=IsChecked, RelativeSource={RelativeSource Self}}"/>
</DataTemplate>
</DataGridCheckBoxColumn.HeaderTemplate>
</DataGridCheckBoxColumn>
<DataGridTemplateColumn Header="Name" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding UsecaseName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
*。cs(ViewModel)
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
for (int i = 0; i < 100; i++)
{
MyCollection.Add(new UseCase { UsecaseName = "name " + i, IsSelected = false });
}
MyCommand = new RelayCommand(MyCommandAction);
}
private ObservableCollection<UseCase> myCollection = new ObservableCollection<UseCase>();
public ObservableCollection<UseCase> MyCollection
{
get
{
return myCollection;
}
set
{
myCollection = value;
NotifyPropertyChanged("MyCollection");
}
}
public RelayCommand MyCommand { get; set; }
private void MyCommandAction(object obj)
{
foreach (var item in MyCollection)
{
item.IsSelected = (bool)obj;
}
}
//NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
*。cs(型号)
public class UseCase : INotifyPropertyChanged
{
public string UsecaseName { get; set; }
private bool _isSelected;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
答案 1 :(得分:0)
您可以使用RegisteredAttachedProperty使其成为可能。 Here,你可以找到一个样本。你可以从那里获得灵感。
答案 2 :(得分:0)
尽管存在许多解决方案,但是我想打一个我经常遇到的特定问题陈述,类似于: 在WPF DataGrid中,通过MVVM方法进行绑定,
型号:
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:
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}
};
}
}
查看(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标记标签中添加以下名称空间:
<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 ...
基于this SO answer或this SO answer。
当您访问这些链接时,别忘了投票和鼓励;)
希望对您有所帮助!