如何创建数据模型的副本

时间:2014-06-27 19:23:30

标签: c# wpf mvvm datamodel

在我的程序中,我正在尝试复制数据模型,以便将其设置为另一个用户控件的数据模型。

到目前为止,我已尝试将新数据模型设置为我要复制的数据模型,但所有这些都是将用户控件都指向同一数据模型。

我所做的一个例子:

newUserControl.NewDataModel = oldUserControl.OldDataModel;

如何制作数据模型的副本,以便我可以将其设置为另一个用户控件的数据模型上下文,而不会使UCs瞄准相同的数据模型?

3 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是创建通用扩展方法。这允许您克隆任何对象而不管其类型,只要它是可序列化的(具有“Serializable'”属性)。

public static class ObjectExtensions
{    
    public static T Clone<T>(this T source)
    {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("This type must be serializable.", "source");
            }

            if (Object.ReferenceEquals(source, null))
                return default(T);

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
     }
}

正如@TroelsLarsen所提到的,存在复制事件订阅的风险。为避免这种情况,您可以将NonSerializedAttribute添加到您不希望序列化的字段中。以下是带有示例的MSDN文档。

然后你就这样使用它:

newUserControl.DataModel = oldDataUserControl.DataModel.Clone();

答案 1 :(得分:0)

您在创建新DataModel的类上创建Clone()方法,并复制您需要的属性。

public DataModel Clone() {
    return new DataModel() {
        PropertyA = this.PropertyA,
        PropertyB = this.PropertyB,
        //etc.
    }
}

//OR - Without a clone method:
newUserControl.NewDataModel = new DataModel()
{
    PropertyA = oldUserControl.OldDataModel.PropertyA,
    PropertyB = oldUserControl.OldDataModel.PropertyB,
    //etc
}

详细说明: 这不起作用的原因是简单地将NewDataModel分配给OldDataModal的值意味着仅复制对该对象的引用。换句话说,您没有创建新的DataModel,只是将两个属性都指向同一个实例。

通过创建Clone()方法,您将创建一个与旧的DataModel相同但位于内存中不同位置的新DataModel。

答案 2 :(得分:0)

我要做的是实现消息传递基础架构。这是我以前用过的,它让事情变得容易多了。它本质上是一个事件,您可以在一个控件上设置,然后在另一个控件上订阅该事件,并使用该事件来回传递事物:

http://mvvmlight.codeplex.com/