【问题标题】:Silverlight: How to Make a ShallowCopy of a UIElementSilverlight:如何制作 UIElement 的 ShallowCopy
【发布时间】:2012-11-23 01:10:09
【问题描述】:

我需要将UIElement 添加到两个不同的画布,但一个UIElement 只能是一个画布的子级,因此我必须创建UIElement 的ShallowCopy(不需要DeepCopy)。

我想使用MemberwiseClone,但它受到保护,我不能使用它。

我也想定义一个扩展方法UIElement.ShallowCopy,但是还是调用MemberwiseClone,又被保护了。

编辑:

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

    // 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);
    }

【问题讨论】:

  • 你不能克隆一个对象,除非它被设计成可克隆的。您需要自己复制。

标签: silverlight clone uielement shallow-copy


【解决方案1】:

如果您想在多个 ui 元素中使用某些东西,“同步它们”,那么您应该创建一个 ViewModel 或类似的东西。此视图模型将设置为您要使用的任何元素的数据上下文。那么你的浅层引用很简单,你可以创建两个独立的 UI 元素绑定到相同的数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多