问题描述
我已经实现了 ObservableCollection 的深度克隆,以便通过取消按钮将可编辑 Datagrid 中的项目重置为其原始状态。
为此,我有两个集合 - 一个 ObservableCollection 将 Datagrid 绑定到它,并克隆 List 以在需要时将 ObservableCollection 重新初始化为它的原始状态。
我的代码只在我第一次点击取消按钮时起作用,之后我克隆的 List 也发生了变化。
提供的代码是一个例子(我的有点长),但它和我的 100% 相同:
实现 ICloneable 的模型:
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; }
}
视图模型:
public viewmodel() : Base //Implements InotifyPropertyChanged
{
public viewmodel()
{
Task.Run(()=> GetData());
}
public ObservableCollection<EmployeeModel> Employees
{
get { return _employees; }
set { _employees = value; OnPropertyChanged();}
}
private ObservableCollection<EmployeeModel> _employees;
public List<EmployeeModel> copy_employees
{
get { return _copy_employees; }
set { _copy_employees = value; OnPropertyChanged();}
}
private List<EmployeeModel> _copy_employees;
//Fetch data from DB
private async Task Get_data()
{
//Returns new ObservableCollection of type Employee
Employees = await _procedures.Get_employees();
if (Employees != null) //Now make a deep copy of Collection
{
copy_employees = new List<EmployeeModel>();
copy_employees = Employees.Select(s => (EmployeeModel)s.Clone()).ToList();
}
}
//My Command for canceling changes (reseting DataGrid)
//CanExecute happens,when model is changed - tracking via CHANGE property of EmployeeModel
public void Cancel_Execute(object parameter)
{
Employees.Clear(); //Tried with re-initializing too,but same result
foreach (var item in copy_employees)// Reset binded ObservableCollection with old items
{
Employees.Add(item);
}
//Check if copied List really hasn't got any changes
foreach (EmployeeModel item in copy_employees)
{
Console.WriteLine("Changes are " + item.CHANGES.ToString());
}
}
}
取消命令的输出:
1.) 我第一次点击取消按钮:
// Changes are False
下次:
// Changes are True
所以,正如我从控制台看到的那样,当 ObservableCollection 更新时,我复制的 List 也会更新,即使它没有绑定到 DataGrid。 它只更新我更改的属性,因此 List 反映了 ObservableCollection 项。
如何保留 List<Employee>
的原始项目,并随时将它们复制到绑定的 ObservableCollection 中?
解决方法
当您返回值时,您不会返回它们,而是将支持项引用写入可编辑集合。 因此,您在两个集合中拥有相同的实例。 在最简单的情况下,当您返回它们时,您还需要进行克隆。
public void Cancel_Execute(对象参数) { 员工.清除(); //也尝试过重新初始化,但结果相同
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();
}