2009-12-21 56 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); 
    } 
} 
相关问题