为自动生成列的DataGrid复选框注册事件处理,实现批量勾选
搞定动态列DataGrid的批量复选框同步功能
嘿,我来帮你解决这个DataGrid的需求!你要的是带自动生成列的DataGrid,第一列固定复选框,而且选中多行后勾选其中一个,所有选中行的复选框都得同步勾选对吧?我给你一步步拆解实现方案:
一、先搞定「自动生成列+固定第一列复选框」
因为是自动生成列,没法硬编码列顺序,所以我们可以通过监听AutoGeneratingColumn事件来调整,把复选框列牢牢钉在第一位置。
1. XAML基础布局
先把DataGrid的架子搭好,开启自动生成列,设置多选模式,同时先定义好复选框列:
<DataGrid x:Name="dynamicDataGrid" AutoGenerateColumns="True" SelectionMode="Extended" <!-- 支持按住Ctrl/Shift多选 --> AutoGeneratingColumn="DynamicDataGrid_AutoGeneratingColumn"> <!-- 先把复选框列定义好,后面用事件调整顺序 --> <DataGrid.Columns> <DataGridCheckBoxColumn x:Name="selectColumn" Header="选择" Binding="{Binding IsSelected, Mode=TwoWay}" /> </DataGrid.Columns> </DataGrid>
2. 后台调整列顺序
在AutoGeneratingColumn事件里,把自动生成的列都加到复选框列后面,确保复选框永远是第一列:
private void DynamicDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { // 跳过我们自己定义的复选框列,把自动生成的列追加到后面 if (!e.Column.Header.ToString().Equals("选择")) { dynamicDataGrid.Columns.Add(e.Column); e.Cancel = true; // 取消默认的自动添加,避免列重复 } }
二、实现「多选后复选框同步勾选」
这个核心是监听复选框的勾选事件,当某个选中行的复选框被勾上时,遍历所有选中行,把它们的选中状态同步改了。
1. 给数据模型加IsSelected属性
首先你的数据类得实现INotifyPropertyChanged,加个IsSelected属性用来双向绑定复选框:
public class DynamicDataModel : INotifyPropertyChanged { private bool _isSelected; public bool IsSelected { get => _isSelected; set { _isSelected = value; OnPropertyChanged(nameof(IsSelected)); } } // 用ExpandoObject存动态属性,方便自动生成列 public dynamic DynamicProperties { get; set; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 绑定复选框的勾选事件
修改XAML里的复选框列,给它加个样式绑定Checked事件(如果需要取消勾选也同步,就再加个Unchecked事件):
<DataGridCheckBoxColumn x:Name="selectColumn" Header="选择" Binding="{Binding IsSelected, Mode=TwoWay}"> <DataGridCheckBoxColumn.ElementStyle> <Style TargetType="CheckBox"> <EventSetter Event="Checked" Handler="SelectCheckBox_Checked" /> <EventSetter Event="Unchecked" Handler="SelectCheckBox_Unchecked" /> </Style> </DataGridCheckBoxColumn.ElementStyle> </DataGridCheckBoxColumn>
3. 后台写同步逻辑
在勾选/取消勾选事件里,拿到当前选中的所有行,统一设置它们的选中状态:
private void SelectCheckBox_Checked(object sender, RoutedEventArgs e) { var checkBox = sender as CheckBox; var selectedItem = checkBox.DataContext as DynamicDataModel; if (selectedItem != null && dynamicDataGrid.SelectedItems.Count > 1) { // 遍历所有选中的项,统一设置为选中状态 foreach (var item in dynamicDataGrid.SelectedItems.OfType<DynamicDataModel>()) { item.IsSelected = true; } } } // 取消勾选的同步逻辑 private void SelectCheckBox_Unchecked(object sender, RoutedEventArgs e) { var checkBox = sender as CheckBox; var selectedItem = checkBox.DataContext as DynamicDataModel; if (selectedItem != null && dynamicDataGrid.SelectedItems.Count > 1) { foreach (var item in dynamicDataGrid.SelectedItems.OfType<DynamicDataModel>()) { item.IsSelected = false; } } }
三、动态数据加载示例
如果你的数据是不确定属性数量的(比如从数据库/接口动态返回),可以用ExpandoObject来创建动态对象,DataGrid会自动识别并生成对应列:
private void LoadDynamicData() { var dataList = new List<DynamicDataModel>(); // 模拟5条动态数据,每条可以自定义属性数量 for (int i = 0; i < 5; i++) { dynamic dynamicProps = new ExpandoObject(); dynamicProps.ID = i + 1; dynamicProps.名称 = $"测试项{i + 1}"; dynamicProps.数值 = i * 15; // 可按需添加更多属性,DataGrid会自动生成对应列 dataList.Add(new DynamicDataModel { DynamicProperties = dynamicProps }); } dynamicDataGrid.ItemsSource = dataList; }
这样一套下来,就能完美实现你要的所有功能:自动生成任意数量的列,第一列固定复选框,多选后勾选任意一个复选框,所有选中行的复选框都会同步切换状态~
内容的提问来源于stack exchange,提问作者PatH
相关产品推荐
相关产品推荐

