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

如何从代码后台访问资源字典中的CollectionViewSource以重置DataGrid数据?

解决DataGrid取消新增时恢复初始状态的问题

我来给你捋捋怎么搞定这个需求——既然你的CollectionViewSource(简称CVS)藏在ResourceDictionary里,后台代码不是直接拿不到嘛,其实有办法绕开这个限制,核心思路是先保存初始数据的副本,取消时把副本替换回去,具体步骤如下:

1. 从资源字典里获取CVS实例

后台代码可以用FindResource方法找到定义在资源里的CVS,只要你知道它的键名就行:

// 替换成你自己的CVS键名,比如"YourDataCVS"
var dataCvs = (CollectionViewSource)this.FindResource("YourDataCVS");

如果CVS是在应用级别的ResourceDictionary里,就换成Application.Current.FindResource("YourDataCVS")来获取。

2. 提前保存初始数据的深拷贝

在页面加载、数据首次绑定的时候,一定要把原始数据做个深拷贝存起来——要是只做浅拷贝,后续修改DataGrid里的数据会连带着修改副本,那就白存了。举个例子,假设你的数据源是ObservableCollection<YourDataModel>:

// 类级别的变量,用来存原始数据副本
private ObservableCollection<YourDataModel> _originalDataBackup;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var dataCvs = (CollectionViewSource)this.FindResource("YourDataCVS");
    var currentSource = dataCvs.Source as ObservableCollection<YourDataModel>;
    
    // 这里用Json序列化/反序列化做深拷贝,需要引用Newtonsoft.Json
    _originalDataBackup = JsonConvert.DeserializeObject<ObservableCollection<YourDataModel>>(
        JsonConvert.SerializeObject(currentSource)
    );
    
    // 要是不想用第三方库,也可以手动遍历每个对象复制属性:
    // _originalDataBackup = new ObservableCollection<YourDataModel>();
    // foreach (var item in currentSource)
    // {
    //     _originalDataBackup.Add(new YourDataModel 
    //     {
    //         Id = item.Id,
    //         Name = item.Name,
    //         // 把模型的所有属性都复制一遍
    //     });
    // }
}

3. 取消操作时恢复原始数据

当用户点击取消按钮时,把当前CVS的数据源替换回我们保存的副本就行,有两种方式可选:

方式一:清空当前集合,再添加原始数据

这种方式适合不想改变集合引用的场景:

private void CancelBtn_Click(object sender, RoutedEventArgs e)
{
    var dataCvs = (CollectionViewSource)this.FindResource("YourDataCVS");
    var currentCollection = dataCvs.Source as ObservableCollection<YourDataModel>;
    
    currentCollection.Clear();
    // 注意这里最好也复制一遍副本里的对象,避免后续修改影响备份
    foreach (var item in _originalDataBackup)
    {
        currentCollection.Add(new YourDataModel 
        {
            Id = item.Id,
            Name = item.Name
        });
    }
}

方式二:直接替换CVS的Source

这种方式更简洁,直接给CVS的Source赋值新的集合:

private void CancelBtn_Click(object sender, RoutedEventArgs e)
{
    var dataCvs = (CollectionViewSource)this.FindResource("YourDataCVS");
    // 同样要做一次对象复制,保证备份不被修改
    var restoredCollection = new ObservableCollection<YourDataModel>(
        _originalDataBackup.Select(item => new YourDataModel 
        {
            Id = item.Id,
            Name = item.Name
        })
    );
    dataCvs.Source = restoredCollection;
}

额外小贴士

如果你的项目用了MVVM模式,其实更推荐把CVS的Source绑定到ViewModel里的可观察集合,这样不用在后台找资源,直接在ViewModel里维护原始数据副本,取消时更新绑定的集合就行,代码会更整洁:

<CollectionViewSource x:Key="YourDataCVS" Source="{Binding YourDataCollection}" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:28:17