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