2009-12-21 11 views
11

कक्षा System.Drawing.Font एक्सएमएल सीरियलज़ेबल नहीं है क्योंकि इसमें डिफ़ॉल्ट (खाली) कन्स्ट्रक्टर नहीं है।
फिर भी Font क्रमबद्ध करने के लिए कुछ काम या वैकल्पिक तरीका है?सिस्टम को XmlSerialize कैसे करें। ड्रॉइंग। फॉन्ट क्लास

उत्तर

19

संपादित करें: मैं जबकि नियमित Font रूप SerializableFont उपयोग करने की क्षमता के संरक्षण, Regent सुझाव FontConverter उपयोग करने के लिए के अनुसार कोड अपडेट किया गया।

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

सच पूछिये तो आप कुछ एक्सएमएल के साथ समाप्त हो गया है जाने के लिए रास्ता नहीं है, लेकिन वास्तव में आप सिर्फ द्वारा एक्सएमएल के सभी अर्थ समृद्धि का सफाया कर दिया गया है बेस 64 एन्कोडेड टेक्स्ट तत्व में अपनी बाइनरी सामग्री को डंप करना। IMHO यह शब्द की उपयोगी अर्थ में वास्तव में "xml serialized" नहीं है। ऐसा नहीं है कि आप एक्सएमएल में किसी भी फ़ॉन्ट गुण को "बिना" बेकार कर सकते हैं, न ही पहले इसे बेकार कर सकते हैं, न ही आप इसे XPath कर सकते हैं, इसे बदल सकते हैं, इसे फिर से चालू कर सकते हैं, –

4

धारावाहिक है कि एक रैपर वर्ग लागू करके इसे कैसे करें इस पर एक सुझाव MSDN page for the Font class पर दिया गया है।

+1

हाँ - वर्ग कि है सही मायने में xml serializable के चारों ओर एक आवरण IMHO –

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

यह समाधान मेरे लिए काम करता है, धन्यवाद! हालांकि यह जानने में दिलचस्पी है कि क्यों न केवल फ़ॉन्ट फ़ॉन्ट कनवर्टर = नया फ़ॉन्ट कनवर्टर(); 'या यह ठीक है? – Ben

+0

बस इसे [एमएसडीएन] (http://msdn.microsoft.com/en-us/library/system.drawing.fontconverter.aspx) पर मिला: यह कहता है कि GetConverter method_ को कॉल करके TypeDescriptor क्लास के माध्यम से FontConverter क्लास को एक्सेस करें। लेकिन अभी भी यकीन नहीं है क्यों। – Ben

+0

@ बेन, मुझे लगता है कि इसके लिए कई कारण हो सकते हैं, सबसे पहले 'टाइपडिस्क्रिप्टर' पहले से ही 'FontConverter' का उदाहरण बना सकता है, इसलिए आपको हर बार एक मेमोरी बनाने की आवश्यकता नहीं है; दूसरी बात यह है कि वे फ्रेमवर्क के भविष्य के संस्करणों में कुछ और के साथ 'FontConverter' को प्रतिस्थापित करना चाहते हैं और' TypeDescriptor' का उपयोग करके इस पर अधिक लचीलापन देता है। – Regent

4

मैं एक serializable फ़ॉन्ट, Elad's से कुछ अलग का उपयोग करें।

मेरी serializable डेटा-संस्थाओं में मैं छिपाने ([XmlIgnore]) Font प्रकार के साथ संपत्ति और SerializableFont प्रकार, है जो serializer द्वारा "खाया" के साथ संपत्ति का खुलासा।

ध्यान दें कि यह केवल 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); 
    } 
} 
संबंधित मुद्दे