WPF实现分组标题Checkbox批量控制组内所有行状态
WPF MVVM实现DataGrid分组头批量控制开关方案
我采用MVVM模式开发WPF+C#应用,通过DataGrid展示PropertyItem类数据,使用ListCollectionView实现分组功能。目前每行已配置Checkbox,可单独控制单个PropertyItem的启用(On)/禁用状态。现在需要在分组的Expander.Header中添加Checkbox,实现一键批量关闭整组PropertyItem,以下是具体实现方案:
步骤1:完善PropertyItem类(实现属性变更通知)
首先让PropertyItem实现INotifyPropertyChanged接口,确保批量修改On属性后UI能同步更新:
using System.ComponentModel; using System.Runtime.CompilerServices; public class PropertyItem : INotifyPropertyChanged { private string _propertyName = string.Empty; private string _pset = string.Empty; private string _mapping = ""; private bool _on = true; public string PropertyName { get => _propertyName; set { _propertyName = value; OnPropertyChanged(); } } public string Pset { get => _pset; set { _pset = value; OnPropertyChanged(); } } public string Mapping { get => _mapping; set { _mapping = value; OnPropertyChanged(); } } public bool On { get => _on; set { _on = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
步骤2:在ViewModel中添加批量控制命令
假设你的ViewModel类(如MainViewModel)中已有chosenConceptProperties和_chosenConcept,添加通用RelayCommand实现和批量关闭分组的方法:
using System.Windows.Input; // 通用RelayCommand实现 public class RelayCommand : ICommand { private readonly Action<object> _execute; private readonly Func<object, bool> _canExecute; public event EventHandler CanExecuteChanged { add => CommandManager.RequerySuggested += value; remove => CommandManager.RequerySuggested -= value; } public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true; public void Execute(object parameter) => _execute(parameter); } // ViewModel核心代码 public class MainViewModel : INotifyPropertyChanged { private EntityConcept _chosenConcept = new EntityConcept(); private ListCollectionView _chosenConceptProperties; public ListCollectionView chosenConceptProperties { get => _chosenConceptProperties; set { _chosenConceptProperties = value; OnPropertyChanged(); } } public ICommand BatchTurnOffGroupCommand { get; } public MainViewModel() { // 初始化数据(根据实际业务替换) _chosenConcept.propertyList = new ObservableCollection<PropertyItem>(); chosenConceptProperties = new ListCollectionView(_chosenConcept.propertyList); chosenConceptProperties.GroupDescriptions.Add(new PropertyGroupDescription("Pset")); // 初始化批量控制命令 BatchTurnOffGroupCommand = new RelayCommand(BatchTurnOffGroup); } private void BatchTurnOffGroup(object parameter) { if (parameter is string psetName) { // 筛选当前分组下的所有项,批量设置为禁用 var groupItems = _chosenConcept.propertyList.Where(item => item.Pset == psetName); foreach (var item in groupItems) { item.On = false; } } } // ViewModel实现属性变更通知 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } // EntityConcept类完善属性变更通知 public class EntityConcept : INotifyPropertyChanged { private string _name; private ObservableCollection<PropertyItem> _propertyList = new ObservableCollection<PropertyItem>(); public ObservableCollection<PropertyItem> propertyList { get => _propertyList; set { _propertyList = value; OnPropertyChanged(); } } public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
步骤3:修改XAML,添加分组头Checkbox
在Expander.Header的Grid中添加Checkbox,绑定ViewModel的批量命令并传递分组名称作为参数:
<Window.Resources> <CollectionViewSource x:Key="cvsTasks"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="Pset"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource> </Window.Resources> <DataGrid x:Name="propertiesTable" ItemsSource="{Binding chosenConceptProperties}" Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" AutoGenerateColumns="False" CanUserAddRows="False" Margin="0,25,0,0" CellEditEnding="propertiesTable_CellEditEnding"> <DataGrid.Columns> <DataGridTextColumn Width="10*" MinWidth="250" Header="Property Name" Binding="{Binding PropertyName}" IsReadOnly="True" FontSize="10" /> <DataGridTextColumn Width="10*" MinWidth="250" Header="Mapping" Binding="{Binding Mapping}" IsReadOnly="False" FontSize="10" /> <DataGridCheckBoxColumn Width="*" MinWidth="50" Header="On/Off" IsReadOnly="False" Binding="{Binding On}"/> </DataGrid.Columns> <DataGrid.GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander x:Name="exp" IsExpanded="True" Background="White" Foreground="Black" BorderThickness="1,1,1,5"> <Expander.Header> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="10*"/> <ColumnDefinition Width="10*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Text="{Binding Path=Name}" Foreground="#2a5fa4" FontWeight="Bold"/> <!-- 新增分组头批量控制Checkbox --> <CheckBox Grid.Column="2" Content="批量关闭" Command="{Binding DataContext.BatchTurnOffGroupCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" CommandParameter="{Binding Name}"/> </Grid> </Expander.Header> <Expander.Content> <ItemsPresenter/> </Expander.Content> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </DataGrid.GroupStyle> </DataGrid>
关键说明
- 分组头的DataContext是
CollectionViewGroup,因此Checkbox的命令需要通过RelativeSource绑定到DataGrid的DataContext(即ViewModel)。 CommandParameter绑定分组的Name(对应Pset字段值),用于在命令中精准筛选目标分组的所有项。- 所有涉及UI更新的类均实现
INotifyPropertyChanged,确保属性变更能实时同步到界面。
内容的提问来源于stack exchange,提问作者Ryan Daley
相关产品推荐
相关产品推荐

