簡體   English   中英

如何 XmlSerialize System.Drawing.Font 類

[英]How to XmlSerialize System.Drawing.Font class

System.Drawing.Font類不是 XML Serializable,因為它沒有默認(空)構造函數。
盡管如此,是否有一些解決方法或替代方法來序列化Font

編輯:我根據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;}

關於如何通過實現可序列化的包裝類來實現此操作的建議在Font類MSDN頁面上給出。

我使用了一個可序列化的字體,與Elad的有些不同。

在我的可序列化數據實體中,我隱藏了( [XmlIgnore] )具有Font類型的屬性,並使用SerializableFont類型公開該屬性,該類型被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);
    }
}

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);
        }
    }
}

試試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());

它過於復雜,仍然不能與 PropertyGrid 一起使用。 這是簡單易行的解決方案。

首先在類中放置以下2個方法。

protected static string FontToString(Font font)
{
    try
    {
        if (font == null)
            return null;

        var converter = TypeDescriptor.GetConverter(typeof(Font));
        return converter.ConvertToString(font);
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.ToString());
    }
    return null;
}

protected static Font StringToFont(string text)
{
    try
    {
        var converter = TypeDescriptor.GetConverter(typeof(Font));
        return (Font)converter.ConvertFromString(text);
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.ToString());
    }
    return null;
}

然后添加屬性。

[Category("General")]
[XmlIgnore]
public Font LogFont
{
    get
    {
        return StringToFont(LogFontValue);
    }
    set
    {
        LogFontValue = FontToString(value);
    }
}

[Browsable(false)]
public string LogFontValue { get; set; } = "Lucida Console, 12pt";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM