3

为什么System.Windows.Clipboard(PresentationCore.dll)对 System.Windows.Thickness(PresentationFramework.dll)不友好但对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“画笔”?

于 2012-11-14T17:30:34.713 回答
1

根据 msdn,PointSerializableAttribute,而Thickness没有。SerializableAttribute不适用于班级成员。这解释了为什么Clipboard.SetData()静默失败,以及为什么Clipboard.GetData()返回垃圾。

Thickness您可以围绕该 implementsISerializable和 has编写一个包装器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 回答