如何XmlSerialize System.Drawing.Font类

时间:2009-12-21 13:35:10

标签: c# .net serialization

System.Drawing.Font不是XML Serializable,因为它没有默认(空)构造函数 是否有一些解决方法或其他方法来序列化Font

5 个答案:

答案 0 :(得分: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;}

答案 1 :(得分:4)

MSDN page for the Font class上给出了如何通过实现可序列化的包装类来实现此目的的建议。

答案 2 :(得分: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);
    }
}

答案 3 :(得分: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);
        }
    }
}

答案 4 :(得分: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());