1

UIElementを2 つの異なるキャンバスに追加する必要がありますが、一方は 1 つのキャンバスUIElementの子にしかできないため、の ShallowCopy (DeepCopy は不要) を作成する必要がありUIElementます。

を使いたい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);
    }
4

1 に答える 1

1

複数のUI要素で使用したいものがある場合は、「それらを同期」してから、ViewModelまたは同様のものを作成する必要があります。このビューモデルは、使用する要素のデータ コンテキストに設定されます。次に、浅い参照は単純で、同じデータにバインドする 2 つの独立した UI 要素を作成するだけです。

于 2013-02-23T23:30:18.940 に答える