C# WPF应用中如何获取DataGrid选中单元格的当前列实现RowFilter筛选
问题核心成因
- 焦点丢失导致选中状态失效:点击筛选按钮时,WPF的焦点会从DataGrid的当前选中单元格自动切换到按钮控件,此时
CurrentCell、CurrentColumn属性会被重置为默认值(空值/返回0),根本读不到之前选中的列信息。 - 动态列名的取值逻辑错误:直接将
DataGridColumn对象拼接为字符串传入RowFilter,无法得到DataTable中定义的真实列名;且RowFilter语法错误地给列名加了单引号,正确语法中列名不需要用单引号包裹,仅字符串类型的匹配值需要加单引号。 - 列头文字和真实列名不匹配:直接读取
Column.Header当列名使用时,一旦列头设置了自定义显示文本(和DataTable实际列名不一致),RowFilter就会因为找不到对应列直接报错。
分步实现方案
1. 保留选中列信息
两种方式任选即可解决点按钮丢选中状态的问题:
- 在类中定义全局字段存储当前选中的目标列名,通过DataGrid的
CurrentCellChanged事件实时更新字段值,不依赖点击按钮时的实时状态读取。 - 给筛选按钮设置
Focusable="False",从根源上避免点击按钮时抢走DataGrid的输入焦点,让CurrentCell状态始终保留。
2. 正确读取DataTable对应的真实列名
根据DataGrid的列生成方式选择取值逻辑:
- 手动定义列的场景:给每一列的
Tag属性赋值对应的DataTable实际列名,读取时直接取Column.Tag的值即可。 - 自动生成列(
AutoGenerateColumns="True")的场景:从列的绑定表达式中提取真实列名,通过((Binding)currentColumn.DisplayMemberBinding).Path.Path即可拿到绑定到DataTable的实际列名。
3. 修正RowFilter拼接逻辑
列名用方括号包裹(兼容带空格、特殊字符的列名),字符串匹配值用单引号包裹,同时要将用户输入中的单引号做转义处理(替换为两个连续单引号),避免触发语法错误。
可运行的参考代码
// 类级全局字段:存储当前选中的待筛选列的真实列名 private string _currentFilterColumn = string.Empty; // DataGrid的CurrentCellChanged事件,实时更新选中列 private void DataGrid1_CurrentCellChanged(object sender, EventArgs e) { if (DataGrid1.CurrentCell == null || DataGrid1.CurrentCell.Column == null) return; var selectedColumn = DataGrid1.CurrentCell.Column; // 优先读取手动存在Tag里的列名 if (selectedColumn.Tag != null) { _currentFilterColumn = selectedColumn.Tag.ToString(); } // 自动生成列的场景,从绑定路径提取列名 else if (selectedColumn.DisplayMemberBinding is Binding binding) { _currentFilterColumn = binding.Path.Path; } } // 筛选按钮的点击事件 private void Filter_Click(object sender, RoutedEventArgs e) { // 前置校验 if (string.IsNullOrEmpty(_currentFilterColumn)) { MessageBox.Show("请先点击选中需要筛选的列的任意单元格"); return; } if (string.IsNullOrWhiteSpace(FilterText.Text)) { MessageBox.Show("请输入筛选的匹配内容"); return; } DataView DV1 = DT1.DefaultView; // 拼接正确的RowFilter语法,转义用户输入的单引号 DV1.RowFilter = $"[{_currentFilterColumn}] = '{FilterText.Text.Replace("'", "''")}'"; DataGrid1.ItemsSource = DV1; }
额外优化提示
- 若需要模糊匹配效果,将RowFilter中的等于号替换为
like,并在匹配值两侧加通配符:[{_currentFilterColumn}] like '%{FilterText.Text.Replace("'", "''")}%' - 如果需要清空筛选效果,直接给
RowFilter赋值为空字符串即可。
内容的提问来源于stack exchange,提问作者Mario Allw
相关产品推荐
相关产品推荐

