3

我有一个相当标准的要求——我需要能够打开一个对话框,用户可以在其中更改数据绑定字段中的值,然后选择单击“确定”或“取消”,单击“取消”会恢复更改。

我看过IEditableCollectionView,IEditableObjectBindingGroups,但它们似乎都是为了一次编辑一个项目。我的程序在列表中提供了一组对象,用户从列表中选择一个项目并使用SelectedItem-bound TextBoxes 对其进行编辑。这意味着可以编辑任意数量的项目,包括从列表中添加和删除它们,如果他按下取消,所有这些更改都需要还原。

起初我只是通过深拷贝(序列化)进行对象备份并在取消时恢复它们,但现在对象必须包含对其他共享对象的引用,这使得这种方法存在问题。

在不来回手动复制对象和/或值的情况下处理这种情况的最佳方法是什么?

4

3 回答 3

1

在这种情况下,DataTable类将完美运行。它可以保存更改、返回(逐步)或还原所有更改和许多其他功能。DataTable 类有一个与 XML 配合得很好的嵌套特性。

如果您愿意保存在数据库中,请查看EntityFramework

于 2013-01-20T16:13:31.763 回答
0

经过对此事的更多思考,我得出的结论是,至少对于小规模实施而言,最好的方法是编写一个“按值深拷贝”方法,该方法复制对象字段和属性的值而不替换对象本身(这样即使恢复数据,对已编辑对象的任何引用仍保持不变)。

为此,我编写了以下扩展方法:

public static void CopyDataTo(this Object source, Object target) {
    // Recurse into lists
    if (source is IList) {
        var a = 0;
        foreach (var item in (IList)source) {
            if (a >= ((IList)target).Count) {
                var type = item.GetType();
                var assembly = Assembly.GetAssembly(type);
                var newItem = assembly.CreateInstance(type.FullName);
                ((IList)target).Add(newItem);
            }
            item.CopyDataTo(((IList)target)[a]);
            a++;
        }
        while (a < ((IList)target).Count) {
            ((IList)target).RemoveAt(a);
        }
    }

    // Copy over fields
    foreach (var field in source.GetType().GetFields())
        field.SetValue(target, field.GetValue(source));
    // Copy properties
    foreach (var property in source.GetType().GetProperties().Where(
        property => property.CanWrite && !property.GetMethod.GetParameters().Any()))
    {
        property.SetValue(target, property.GetValue(source));
    }
}

这不是灵丹妙药:它只适用于相同类型的对象,列表项必须有一个无参数的构造函数,并且无法控制递归深度。此外,我还没有机会在任何长期或更复杂的场景中进行测试,但到目前为止它做了它应该做的(在对象之间复制值)并且可以用于简单的备份/恢复场景:

var backup = new TypeOfVariableToEdit();
data.CopyDataTo(backup);
var clickedOK = RunDataEditor(data);
if (!clickedOK)
    backup.CopyDataTo(data);
于 2013-01-20T16:58:42.247 回答
-1

最好的方法是不要:

如果您需要这些项目,请从数据库或任何数据存储中获取它们的新副本,允许用户进行更改,如果他们按下取消,则丢弃更改。如果他们按保存,将数据保存到存储中,然后刷新现有屏幕或其他任何内容。

于 2013-01-20T16:34:53.413 回答