Wpf 可观察收集深度克隆

Wpf 可观察收集深度克隆,wpf,observablecollection,deep-copy,Wpf,Observablecollection,Deep Copy,我已经实现了ObservableCollection的深度克隆,以便通过取消按钮将项目重置为可编辑数据网格中的原始状态 为此,我有两个集合——一个用于将Datagrid绑定到它的ObservableCollection,以及一个用于在需要时将ObservableCollection重新初始化为其原始状态的克隆列表 我的代码只有在我第一次按下“取消”按钮时才起作用,之后我的克隆列表也发生了变化 提供的代码是一个示例(我的代码稍长),但它与我的代码100%相同: 实现iClonable的模型: pu

我已经实现了ObservableCollection的深度克隆,以便通过取消按钮将项目重置为可编辑数据网格中的原始状态

为此,我有两个集合——一个用于将Datagrid绑定到它的ObservableCollection,以及一个用于在需要时将ObservableCollection重新初始化为其原始状态的克隆列表

我的代码只有在我第一次按下“取消”按钮时才起作用,之后我的克隆列表也发生了变化

提供的代码是一个示例(我的代码稍长),但它与我的代码100%相同:

实现iClonable的模型:

public class EmployeeModel : ICloneable
{
   public object Clone()
   {
       return MemberwiseClone();
   }
    
   public string NAME
   {
      get { return _name; }
      set
         {
            if (_name != value)
            {
               CHANGE = true;
                _name = value;
             }
          }
     }
     private string _name;

     public string SURNAME
     {
        get { return _surname; }
        set
         {
            if (_surname != value)
            {
               CHANGE = true;
                _surname = value;
             }
          }
     }
     private string _surname; 

     ///<summary>Property for tracking changes in model</summary>
     public bool CHANGE { get; set; }
}
下次:

// Changes are True
所以,正如我从控制台看到的,当ObservableCollection get更新时,我复制的列表get也会更新,即使它没有绑定到DataGrid。 它只更新了我更改过的一个属性,所以列表反映了可观察的集合项


我如何保留我的原始项目的
列表
并随时将其复制到绑定的ObservableCollection中?

当您返回值时,您不返回值,而是将支持项引用写入可编辑集合。 因此,两个集合中的实例相同。 在最简单的情况下,返回它们时,还需要克隆

public void Cancel_Execute(对象参数) { Employees.Clear();//也尝试了重新初始化,但结果相同

    foreach (var item in Copy_employees)// Reset binded ObservableCollection with old items
    {
         Employees.Add((EmployeeModel)item.Clone());
    }
     
    //Check if copied List really hasn't got any changes                    
    foreach (EmployeeModel item in Copy_employees)
    {
       Console.WriteLine("Changes are " + item.CHANGES.ToString());
    }

 }
与问题无关,但我仍然建议您使用更友好的用户界面来实现cloneable:

public interface ICloneable<T> : ICloneable
{
    new T Clone();
}
公共接口ICloneable:ICloneable
{
新T克隆();
}

我们不使用memberwiseclone。这会复制对对象的引用。请看一看..但就我个人而言,我通常使用automapper将dto复制到viewmodels中。@Andy:显示的代码只包括
EmployeeModel
对象中的不可变字段,所以通常你是对的
memberwiseclone()
不会进行深度复制,实际上这在这里并不重要。您发布的代码不会显示任何类型的
ToString()
覆盖
EmployeeModel
,因此代码不可能输出任何看起来像
更改为假的文本
。由于缺少正确的答案,无法知道实际发生了什么,因此无法为这个问题提供好的答案。@PeterDuniho,我刚刚编辑了它,没有看到,抱歉。@Andy,我已经尝试在你提供的链接中接受答案,但它没有用C语言编译。非常感谢你,我不会在几天内找到答案。尽管我很抱歉仍然很困惑-当我返回项目时,我需要再次克隆它们。如果没有可编辑集合的项目引用,它们不是第一次克隆的,那么为什么第二次克隆可以工作呢?也感谢界面。但我决定放弃IClonable界面,坚持安迪提出的方法-使用seriali深度克隆对象的解决方案序列化。这至少是一种更干净的代码。再次感谢!!!如果您不每次克隆,那么您将获得指向不同集合中相同实例的链接。为了正确工作,您需要两个具有不同(尽管等效)样本的集合。在这项任务中,序列化在所需资源方面是非常冗余和不合理的。
ICloneableI
Cloneable
通过
MemberwiseClone()实现
在这里就足够了。当克隆的对象包含对引用类型的其他可变实例的引用时,将使用序列化。在实体类型
EmployeeModel
中没有此类引用。即使是这样,类型本身也必须知道它,并且它必须自己决定应该额外克隆什么获取深度副本。感谢提供更多信息。
    foreach (var item in Copy_employees)// Reset binded ObservableCollection with old items
    {
         Employees.Add((EmployeeModel)item.Clone());
    }
     
    //Check if copied List really hasn't got any changes                    
    foreach (EmployeeModel item in Copy_employees)
    {
       Console.WriteLine("Changes are " + item.CHANGES.ToString());
    }

 }
public interface ICloneable<T> : ICloneable
{
    new T Clone();
}