2009-12-21 68 views

回答

19

編輯:我根據Regent建議使用FontConverter更新的代碼,同時保留使用SerializableFont定期Font的能力。

public class SerializableFont 
{ 
    public SerializableFont() 
    { 
     FontValue = null; 
    } 

    public SerializableFont(Font font) 
    { 
     FontValue = font; 
    } 

    [XmlIgnore] 
    public Font FontValue { get; set; } 

    [XmlElement("FontValue")] 
    public string SerializeFontAttribute 
    { 
     get 
     { 
      return FontXmlConverter.ConvertToString(FontValue); 
     } 
     set 
     { 
      FontValue = FontXmlConverter.ConvertToFont(value); 
     } 
    } 

    public static implicit operator Font(SerializableFont serializeableFont) 
    { 
     if (serializeableFont == null) 
      return null; 
     return serializeableFont.FontValue; 
    } 

    public static implicit operator SerializableFont(Font font) 
    { 
     return new SerializableFont(font); 
    } 
} 

public static class FontXmlConverter 
{ 
    public static string ConvertToString(Font font) 
    { 
     try 
     { 
      if (font != null) 
      { 
       TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); 
       return converter.ConvertToString(font); 
      } 
      else 
       return null; 
     } 
     catch { System.Diagnostics.Debug.WriteLine("Unable to convert"); } 
     return null; 
    } 
    public static Font ConvertToFont(string fontString) 
    { 
     try 
     { 
      TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); 
      return (Font)converter.ConvertFromString(fontString); 
     } 
     catch { System.Diagnostics.Debug.WriteLine("Unable to convert"); } 
     return null; 
    } 
} 

用法:當你有一個Font屬性,聲明爲SerializableFont。這將允許它被序列化,而隱式轉換將爲您處理轉換。

而是寫的:

Font MyFont {get;set;} 

寫:

SerializableFont MyFont {get;set;} 
+6

嚴格地說你已經結束了與一些XML的方式,但在現實中,你已經通過只是消除了XML的所有語義豐富性將其二進制內容轉儲到base64編碼的文本元素中。恕我直言,這實際上不是「xml序列化」在這個詞的有用意義上。 這不是你可以在XML中「看到」任何字體屬性,而無需首先反序列化,也不能XPath它,轉換它,遍歷它等等。 – 2009-12-21 13:58:25

4

關於如何通過實現可序列化的包裝類來實現此目的的建議在MSDN page for the Font class上給出。

+1

是 - 這是真正的XML序列化類周圍的包裝是去恕我直言 – 2009-12-21 13:59:37

1

嘗試DataContractSerializer的。

 Font fnt = new Font("Arial", 1); 
     MemoryStream data = new MemoryStream(); 
     DataContractSerializer dcs = new DataContractSerializer(typeof(Font), new[] { typeof(FontStyle), typeof(GraphicsUnit) }); 
     dcs.WriteObject(data, fnt); 
     string xml = Encoding.UTF8.GetString(data.ToArray()); 
2

System.Drawing.Font具有相關聯的類FontConverter,我會手動將其轉換:

[Serializable] 
public class SerializableFont 
{ 
    public SerializableFont() 
    { 
     this.Font = null; 
    } 

    public SerializableFont(Font font) 
    { 
     this.Font = font; 
    } 

    [XmlIgnore] 
    public Font Font { get; set; } 

    [XmlElement("Font")] 
    public string FontString 
    { 
     get 
     { 
      if (font != null) 
      { 
       TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); 

       return converter.ConvertToString(this.Font); 
      } 
      else return null; 
     } 
     set 
     { 
      TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); 

      this.Font = converter.ConvertFromString(value); 
     } 
    } 
} 
+0

這個解決方案對我有用,謝謝!雖然有興趣知道爲什麼不使用'FontConverter轉換器=新的FontConverter();'或者這是好嗎? – Ben 2012-04-17 15:03:05

+0

剛剛在[MSDN](http://msdn.microsoft.com/en-us/library/system.drawing.fontconverter.aspx)上找到了它:它表示_Access通過調用GetConverter method_通過TypeDescriptor類FontConverter類。但仍然不知道爲什麼。 – Ben 2012-04-17 15:29:09

+0

@Ben,我認爲這可能有幾個原因,首先'TypeDescriptor'可能已經創建了'FontConverter'實例,因此您不需要浪費內存來創建每一次;其次,他們可能想在未來版本的框架中用'其他的'替換'FontConverter',並且使用'TypeDescriptor'可以提供更多的靈活性。 – Regent 2012-04-25 10:02:07

4

我使用的可序列化的字體,從Elad's有些不同。

在我的可序列化的數據實體中,我隱藏([XmlIgnore]Font類型的屬性,並暴露屬性爲SerializableFont類型,串行器「吃掉」它。請注意,這僅適用於XmlSerializer

/// <summary> 
/// Font descriptor, that can be xml-serialized 
/// </summary> 
public class SerializableFont 
{ 
    public string FontFamily { get; set; } 
    public GraphicsUnit GraphicsUnit { get; set; } 
    public float Size { get; set; } 
    public FontStyle Style { get; set; } 

    /// <summary> 
    /// Intended for xml serialization purposes only 
    /// </summary> 
    private SerializableFont() { } 

    public SerializableFont(Font f) 
    { 
     FontFamily = f.FontFamily.Name; 
     GraphicsUnit = f.Unit; 
     Size = f.Size; 
     Style = f.Style; 
    } 

    public static SerializableFont FromFont(Font f) 
    { 
     return new SerializableFont(f); 
    } 

    public Font ToFont() 
    { 
     return new Font(FontFamily, Size, Style, 
      GraphicsUnit); 
    } 
} 
相關問題