剪贴板+ PresentationFramework = OutOfMemoryException?

时间:2012-11-14 16:51:02

标签: c# .net wpf clipboard

为什么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; }

    }
}

2 个答案:

答案 0 :(得分:5)

Brush类不可序列化并导致抛出OutOfMemoryException(请参阅http://www.grumpydev.com/2009/09/05/system-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf/)。您可以将Test类序列化为XAML并将其放入剪贴板,请参阅此链接以获取信息:

How can i serialize xaml "Brush"?

答案 1 :(得分:1)

根据msdn,PointSerializableAttribute,而Thickness没有SerializableAttributeClipboard.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 } 的包装器,如下所示:

{{1}}