3

Why does System.Windows.Clipboard(PresentationCore.dll) is not friendly with the System.Windows.Thickness (PresentationFramework.dll) but friendly with System.Windows.Point (WindowsBase.dll)

using System;
namespace ConsoleApplication5 {
    class Program {
        /*
        * Add references to 
        * WindowsBase.dll (Point)
        * PresentationFramework.dll (Thickness)
        * PresentationCore.dll (Clipboard)
        */

        [STAThread]
        static void Main(string[] args)
        {
            Test myTest = new Test();
            System.Windows.Clipboard.SetData("myformat", myTest);
            // OutOfMemoryException
            Object myPastedTest = System.Windows.Clipboard.GetData("myformat");
        }
    }

    [Serializable]
    class Test
    {
        // COMMENT THE LINES BELLOW PresentationFramework TO WORK OK!
        // PresentationFramework.dll
        //public System.Windows.Thickness MyThickness { get; set; } 
        public System.Windows.Media.Brush MyBrush { get; set; }

        // WindowsBase.dll
        public System.Windows.Point MyPoint { get; set; }

    }
}
4

2 に答える 2

5

Brushクラスはシリアル化できず、OutOfMemoryExceptionがスローされます(http://www.grumpydev.com/2009/09/05/system-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf/を参照)。TestクラスをXAMLにシリアル化し、代わりにクリップボードに配置できる場合があります。詳細については、次のリンクを参照してください。

xaml "Brush"をシリアル化するにはどうすればよいですか?

于 2012-11-14T17:30:34.713 に答える
1

msdnによると、PointありますがSerializableAttribute、ありThicknessません。はSerializableAttributeクラスメンバーには適用されません。これは、なぜClipboard.SetData()サイレントに失敗し、なぜClipboard.GetData()ガベージを返すのかを説明しています。

Thickness次のように、を実装ISerializableして持つラッパーを作成できますSerializableAttribute

[Serializable]
public struct SerializableThickness : ISerializable
{
    public Thickness Data;

    public SerializableThickness(Thickness t)
    {
        Data = t;
    }

    #region ISerializable
    private const string LeftField = "LeftField";
    private const string TopField = "TopField";
    private const string RightField = "RightField";
    private const string BottomField = "BottomField";

    private SerializableThickness(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");

        var enumerator = info.GetEnumerator();
        bool[] found = { false, false, false, false };
        double[] values = new double[4];
        while (enumerator.MoveNext() && !found.All(x => x))
        {
            switch (enumerator.Name)
            {
                case LeftField:
                    found[0] = true;
                    values[0] = (double)enumerator.Value;
                break;

                case TopField:
                    found[1] = true;
                    values[1] = (double)enumerator.Value;
                break;

                case RightField:
                    found[2] = true;
                    values[2] = (double)enumerator.Value;
                break;

                case BottomField:
                    found[3] = true;
                    values[3] = (double)enumerator.Value;
                break;
            }
        }

        if (!found.All(x => x))
            throw new SerializationException("Missing serializable members");

        Data = new Thickness(values[0], values[1], values[2], values[3]);
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(LeftField, Data.Left);
        info.AddValue(TopField, Data.Top);
        info.AddValue(RightField, Data.Right);
        info.AddValue(BottomField, Data.Bottom);
    }
    #endregion
}
于 2012-11-14T17:30:52.600 に答える