2011-04-07 68 views
0

是否有任何xaml序列化屬性可以爲實際上是集合(TextDecorationCollection)的依賴屬性指定?WPF中的TextDecorationCollection序列化

我想使用序列化克隆一個非常大而複雜的對象。下面的代碼樣本,簡化:

有一個MyVisualObject,包含這樣定義很多的屬性,包括自定義字體,我想克隆

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
public class Export : Attribute 
{ 
} 

public class MyVisualObject : DependencyObject 
{ 
    [Export] 
    public CustomFont Font 
    { 
     get { return (CustomFont)GetValue(FontProperty); } 
     set { SetValue(FontProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Font. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty FontProperty = 
     DependencyProperty.Register("Font", typeof(CustomFont), typeof(MyVisualObject)); 

    public MyVisualObject() 
    { 
     this.Font = new CustomFont(); 
    } 
} 

而自定義字體:

public class CustomFont : DependencyObject 
    { 
     public TextDecorationCollection Decorations 
     { 
      get { return (TextDecorationCollection)GetValue(DecorationsProperty); } 
      set { SetValue(DecorationsProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for TextDecorations. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty DecorationsProperty = 
      DependencyProperty.Register("Decorations", typeof(TextDecorationCollection), typeof(CustomFont), new UIPropertyMetadata(new TextDecorationCollection())); 

     public CustomFont() 
     { 
      this.Decorations = System.Windows.TextDecorations.Underline; 
     } 
    } 

深clone方法:

public static T DeepClone<T>(T from) 
     { 
      object clone = Activator.CreateInstance(from.GetType()); 

      Type t = from.GetType(); 
      System.Reflection.PropertyInfo[] pinf = t.GetProperties(); 

      foreach (PropertyInfo p in pinf) 
      { 
       bool serialize = false; 

       foreach (object temp in p.GetCustomAttributes(true)) 
       { 
        if (temp is Export) 
        { 
         serialize = true; 
        } 
       } 

       if (serialize) 
       { 
        string xaml = XamlWriter.Save(p.GetValue(from, null));       
        XmlReader rd = XmlReader.Create(new StringReader(xaml)); 
        p.SetValue(clone, XamlReader.Load(rd), null); 
       }     
      } 

      return (T)clone; 
     } 

這個問題我s表示每一次我初始化裝飾品如下劃線

this.Decorations = System.Windows.TextDecorations.Underline; 

克隆過程與此錯誤崩潰了:「拋出一個異常‘’添加值類型的集合」 System.Windows.TextDecorationCollection行號「1」和行位置「213」。

至於我發現,序列化,這是這部分

string xaml = XamlWriter.Save(p.GetValue(from, null)); 

返回一個XAML它沒有設置爲收集裝飾品:

<CustomFont xmlns="clr-namespace:WpfApplication1;assembly=WpfApplication1" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 
    <CustomFont.Decorations> 
     <av:TextDecoration Location="Underline" /> 
    </CustomFont.Decorations> 
</CustomFont> 

但克隆過程將工作,如果XAML會是這樣的:

<CustomFont xmlns="clr-namespace:WpfApplication1;assembly=WpfApplication1" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 
    <CustomFont.Decorations> 
     <av:TextDecorationCollection> 
      <av:TextDecoration Location="Underline" /> 
     </av:TextDecorationCollection> 
    </CustomFont.Decorations> 
</CustomFont> 

我找到了解決方法,字符串替換:

xaml = xaml.Replace("<CustomFont.Decorations><av:TextDecoration Location=\"Underline\" /></CustomFont.Decorations>", "<CustomFont.Decorations><av:TextDecorationCollection><av:TextDecoration Location=\"Underline\" /></av:TextDecorationCollection></CustomFont.Decorations>"); 

,但我認爲這是非常髒,我會apreciate如果你能提供一個更清潔的解決方案(指定的裝飾品屬性例子中的屬性)

回答

0

你試過應用以下屬性爲裝飾屬性:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]