Silverlight:如何制作UIElement的ShallowCopy [英] Silverlight: How to Make a ShallowCopy of a UIElement

查看:124
本文介绍了Silverlight:如何制作UIElement的ShallowCopy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在两个不同的画布上添加一个UIElement,但是一个UIElement只能是一个画布的子代,因此我必须创建UIElement的ShallowCopy(不需要DeepCopy).

I need to add a UIElement to two different canvases, but one UIElement can only be a child of ONE canvas, so I have to create a ShallowCopy (DeepCopy not needed) of the UIElement.

我想使用MemberwiseClone,但受保护,不能使用.

I want to use MemberwiseClone, but it's protected, I cannot use it.

我也想定义一个扩展方法UIElement.ShallowCopy,但是它仍然会调用MemberwiseClone,该方法再次受到保护.

I also want to define an extension method UIElement.ShallowCopy, but it sill still call MemberwiseClone, which is protected again.

尝试了以下所有方法,但所有这些方法在Silverlight环境中均失败:

Tried all the following, but all of them failed in Silverlight environment:

    // System.Runtime.Serialization.InvalidDataContractException was unhandled by user code
    // Message=Type 'System.Windows.UIElement' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.
    public static T CloneEx<T>(this T obj) where T : class
    {
        T clone;
        DataContractSerializer dcs = new DataContractSerializer(typeof(T));

        using (MemoryStream ms = new MemoryStream())
        {
            dcs.WriteObject(ms, obj);
            ms.Position = 0;
            clone = (T)dcs.ReadObject(ms);
        }

        return clone;
    }

    // This one also throws Access/Invoke exceptions
    private readonly static object _lock = new object();
    public static T MemberwiseCloneEx<T>(this T obj) where T : class
    {
        if (obj == null)
            return null;

        try
        {
            Monitor.Enter(_lock);

            T clone = (T)Activator.CreateInstance(obj.GetType());

            PropertyInfo[] fields = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            foreach (PropertyInfo field in fields)
            {
                object val = field.GetValue(obj, null);
                field.SetValue(clone, val, null);
            }

            return clone;
        }
        finally
        {
            Monitor.Exit(_lock);
        }
    }

    // System.MethodAccessException was unhandled by user code
    // Message=Attempt by method 'ToonController.ControllerUtils.MemberwiseCloneEx<System.__Canon>(System.__Canon)' to access method 'System.Object.MemberwiseClone()' failed.
    public static T MemberwiseCloneEx<T>(this T obj) where T : class
    {
        if (obj == null)
            return null;

        MethodInfo mi = obj.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);

        if (mi == null)
            return null;

        return (T)mi.Invoke(obj, null);
    }

推荐答案

如果您要在多个ui元素中使用某些内容,请将它们同步化",则应创建一个ViewModel或类似的东西.该视图模型将设置为您要使用它的任何元素的数据上下文.然后,您的浅层引用很简单,您只需创建两个独立的UI元素即可绑定到同一数据.

if you have something that you want to use in multiple ui elements, 'sync them up' then you should create a ViewModel or something similar. This viewmodel would be set to the datacontext of any element you want to use it. Then your shallow reference is simple and you can just create two independent UI elements binding to the same data.

这篇关于Silverlight:如何制作UIElement的ShallowCopy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆