2009-12-21 14 views

Trả lời

19

Edit: tôi cập nhật mã theo Regent gợi ý để sử dụng FontConverter, trong khi vẫn giữ khả năng sử dụng các SerializableFont như thường xuyên 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; 
    } 
} 

Cách sử dụng: Khi bạn có thuộc tính Font, hãy khai báo là SerializableFont. Điều này sẽ cho phép nó được tuần tự hóa, trong khi diễn viên ngầm sẽ xử lý chuyển đổi cho bạn.

Thay vì viết:

Font MyFont {get;set;} 

Viết:

SerializableFont MyFont {get;set;} 
+6

Nói đúng ra bạn đã kết thúc với một số xml, nhưng trong thực tế bạn đã loại bỏ tất cả sự phong phú ngữ nghĩa của xml bằng cách chỉ bán phá giá nội dung nhị phân của nó trong phần tử văn bản được mã hóa base64. IMHO Nó thực sự không phải là "xml serialized" trong ý nghĩa hữu ích của từ đó. Nó không giống như bạn có thể "nhìn thấy" bất kỳ thuộc tính Font nào trong xml, mà không có deserializing đầu tiên, cũng không thể XPath nó, biến đổi nó, lặp qua nó, vv –

4

Đề xuất về cách thực hiện việc này bằng cách triển khai lớp bao bọc có thể tuần tự hóa được cung cấp trên MSDN page for the Font class.

+1

Có - một wrapper xung quanh lớp đó là thực sự xml serializable là con đường để đi IMHO –

1

Thử 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 có liên quan đến FontConverter lớp và tôi sẽ tự chuyển đổi nó:

[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

Giải pháp này làm việc cho tôi, cảm ơn! Mặc dù muốn biết tại sao không chỉ sử dụng 'FontConverter converter = new FontConverter();' hay là ok? – Ben

+0

Chỉ tìm thấy điều này trên [MSDN] (http://msdn.microsoft.com/en-us/library/system.drawing.fontconverter.aspx): Nó nói _Access lớp FontConverter thông qua lớp TypeDescriptor bằng cách gọi phương thức GetConverter_. Nhưng vẫn không chắc tại sao. – Ben

+0

@Ben, tôi nghĩ có thể có một vài lý do cho điều này, trước hết 'TypeDescriptor' có thể đã tạo ra instance' FontConverter', do đó bạn không cần phải lãng phí bộ nhớ mỗi lần một lần; thứ hai, họ có thể muốn thay thế 'FontConverter' bằng một cái gì đó khác trong các phiên bản tương lai của Framework và sử dụng' TypeDescriptor' cho phép linh hoạt hơn về điều này. – Regent

4

tôi sử dụng một phông chữ serializable, hơi khác so với Elad's.

Trong các thực thể dữ liệu có thể tuần tự, tôi ẩn ([XmlIgnore]) thuộc tính với loại Font và hiển thị thuộc tính với loại SerializableFont, được bộ tiếp hợp "ăn".

Lưu ý rằng điều này chỉ áp dụng cho số 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); 
    } 
} 
Các vấn đề liên quan