如何为DataGrid绑定的Matrix集合添加复选框选中属性?
给DataGrid的Matrix集合项添加选中功能的解决方案
嘿,这个需求太常见了,我给你分享两种实用的实现思路,你可以根据自己的场景选:
方案一:用包装类(ViewModel)封装Matrix(推荐)
如果你的Matrix是实体类(比如从数据库/API获取的,不想直接修改它的结构),最稳妥的方式是创建一个包装ViewModel,给每个Matrix对象附加IsSelected属性。
步骤1:创建包装类
先写一个实现了INotifyPropertyChanged的包装类,把原Matrix对象和选中属性包在一起:
public class MatrixItemViewModel : INotifyPropertyChanged { private bool _isSelected; private Matrix _matrix; public bool IsSelected { get => _isSelected; set { if (_isSelected != value) { _isSelected = value; OnPropertyChanged(nameof(IsSelected)); } } } public Matrix Matrix { get => _matrix; set { if (_matrix != value) { _matrix = value; OnPropertyChanged(nameof(Matrix)); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
步骤2:修改你的集合类型
把原来的ObservableCollection<Matrix>改成ObservableCollection<MatrixItemViewModel>:
private ObservableCollection<MatrixItemViewModel> _matriceItems; public ObservableCollection<MatrixItemViewModel> MatriceItems { get => _matriceItems; set { if (value != _matriceItems) { _matriceItems = value; RaisePropertyChanged(nameof(MatriceItems)); } } } // 初始化的时候把获取到的Matrix转成包装类 var rawMatrices = await _dataService.GetMatrice(idMatrice); MatriceItems = new ObservableCollection<MatrixItemViewModel>( rawMatrices.Select(m => new MatrixItemViewModel { Matrix = m }) );
步骤3:绑定DataGrid的列
在XAML里给DataGrid加一个CheckBox列,绑定到IsSelected,其他列绑定到Matrix的属性:
<DataGrid ItemsSource="{Binding MatriceItems}" AutoGenerateColumns="False"> <!-- 复选框列 --> <DataGridCheckBoxColumn Header="选中" Binding="{Binding IsSelected}" /> <!-- 原有的数据列 --> <DataGridTextColumn Header="日期" Binding="{Binding Matrix.Date}" /> <DataGridTextColumn Header="名称" Binding="{Binding Matrix.Name}" /> <!-- 其他列... --> </DataGrid>
步骤4:获取选中的项
要拿到选中的Matrix列表,直接筛选就行:
var selectedMatrices = MatriceItems.Where(item => item.IsSelected) .Select(item => item.Matrix) .ToList();
方案二:用WPF附加属性(无需修改原类)
如果你不想创建包装类,可以用WPF的附加属性来给DataGridRow绑定选中状态,这种方式不需要修改Matrix类或集合类型。
步骤1:创建附加属性类
public static class DataGridRowSelectionHelper { public static readonly DependencyProperty IsRowSelectedProperty = DependencyProperty.RegisterAttached( "IsRowSelected", typeof(bool), typeof(DataGridRowSelectionHelper), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault) ); public static bool GetIsRowSelected(DependencyObject obj) { return (bool)obj.GetValue(IsRowSelectedProperty); } public static void SetIsRowSelected(DependencyObject obj, bool value) { obj.SetValue(IsRowSelectedProperty, value); } }
步骤2:在DataGrid中使用附加属性
在XAML里给DataGrid的RowStyle设置附加属性的绑定,同时加一个CheckBox列绑定到这个附加属性:
<DataGrid ItemsSource="{Binding Matrice}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridCheckBoxColumn Header="选中" Binding="{Binding Path=(local:DataGridRowSelectionHelper.IsRowSelected), RelativeSource={RelativeSource AncestorType=DataGridRow}}" /> <DataGridTextColumn Header="日期" Binding="{Binding Date}" /> <DataGridTextColumn Header="名称" Binding="{Binding Name}" /> <!-- 其他列... --> </DataGrid.Columns> </DataGrid>
步骤3:获取选中的项
这种方式需要遍历DataGrid的行来获取选中项:
var selectedMatrices = new List<Matrix>(); foreach (var item in MyDataGrid.Items) { var row = MyDataGrid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; if (row != null && DataGridRowSelectionHelper.GetIsRowSelected(row)) { selectedMatrices.Add(item as Matrix); } }
两种方案各有优劣:
- 方案一更符合MVVM模式,逻辑清晰,获取选中项也更方便,推荐优先用这个。
- 方案二适合快速实现,不需要改动现有集合结构,但获取选中项的代码稍繁琐。
内容的提问来源于stack exchange,提问作者Sephystos
相关产品推荐
相关产品推荐

