You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF/C#:通过DataView筛选时如何更新DataSet?

解决DataGrid筛选后切换ItemsSource时DataSet不更新的问题

嘿,我看你遇到的问题是筛选功能能正常工作,但切换ItemsSource的时候DataSet没法同步更新对吧?大概率是你直接替换ItemsSource的方式切断了原DataSet和DataGrid之间的绑定关联,咱们来一步步解决这个问题:

问题根源分析

你当前的代码是直接把新创建的DataView赋值给DG.ItemsSource,这种做法相当于把DataGrid的数据源直接换成了一个独立的视图对象,和原始的DataSet/DataTable失去了双向绑定的联动——所以后续不管你怎么切换视图,DataSet都感知不到变化,自然不会更新。

修正方案:用CollectionViewSource管理筛选(推荐)

更好的做法是通过CollectionViewSource来维护数据源和筛选规则,这样既能保留和原DataSet的绑定,又能动态切换筛选状态:

  1. 先初始化CollectionViewSource
    可以在窗口初始化或者ViewModel里创建好,绑定到你的DataTable:

    private CollectionViewSource _dataViewSource;
    
    // 初始化(比如在窗口Loaded事件里)
    _dataViewSource = new CollectionViewSource();
    _dataViewSource.Source = DT; // DT是你的原始DataTable
    DG.ItemsSource = _dataViewSource.View;
    
  2. 修改OnlyActiveClick方法,通过Filter切换筛选
    不用再重新创建DataView,而是直接修改视图的筛选器:

    private void OnlyActiveClick(DataTable DT, string ColumnName, DataGrid DG, Tile OnlyActiveTile, bool ToggleActive)
    {
        if (ToggleActive)
        {
            // 启用筛选:只显示"Active"的条目(假设ColumnName对应的值是bool类型)
            _dataViewSource.View.Filter = item =>
            {
                DataRowView rowView = item as DataRowView;
                return rowView != null && (bool)rowView[ColumnName]; // 根据实际列类型调整判断逻辑
            };
            OnlyActiveTile.IsSelected = true;
        }
        else
        {
            // 关闭筛选:恢复显示所有条目
            _dataViewSource.View.Filter = null;
            OnlyActiveTile.IsSelected = false;
        }
        // 强制刷新视图确保筛选生效
        _dataViewSource.View.Refresh();
    }
    

如果你坚持用DataView的替代方案

如果不想用CollectionViewSource,那要确保切换时始终关联原始DataTable的视图,而不是创建新的独立视图:

private void OnlyActiveClick(DataTable DT, string ColumnName, DataGrid DG, Tile OnlyActiveTile, bool ToggleActive)
{
    if (ToggleActive)
    {
        // 基于原DataTable创建带筛选的DataView,保留和原表的关联
        DataView filteredView = new DataView(DT);
        filteredView.RowFilter = $"{ColumnName} = true"; // 根据列类型写筛选表达式,比如数值型可以写ColumnName = 1
        DG.ItemsSource = filteredView;
        OnlyActiveTile.IsSelected = true;
    }
    else
    {
        // 切换回原DataTable的默认视图,而非创建新对象
        DG.ItemsSource = DT.DefaultView;
        OnlyActiveTile.IsSelected = false;
    }
    // 注意:如果需要DataSet感知数据编辑,确保DataView的AllowEdit/AllowNew等属性处于开启状态(默认开启)
    // 同时DataGrid中数据项的绑定模式设为TwoWay,才能让编辑内容回写到DataSet
}

额外注意点

  • 如果你用的是MVVM模式,建议把筛选逻辑放到ViewModel里,通过绑定ICollectionView的Filter属性实现,更符合WPF的设计思想。
  • 确认你的DataTable是DataSet的一部分,这样DataGrid的数据源变更才能同步到DataSet中。

内容的提问来源于stack exchange,提问作者Ginjo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:55:45