Как XmlSerialize System.Drawing.Font класс

Класс System.Drawing.Font не является XML Serializable, поскольку он не имеет конструктора по умолчанию (пустой).
Есть ли какая-нибудь работа или альтернативный способ сериализации Font тем не менее?

Ответ 1

Изменить: Я обновил код в соответствии с предложением 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;}

Ответ 2

Предложение о том, как это сделать, путем реализации класса-оболочки, сериализуемого, приведено на

Ответ 3

Я использую сериализуемый шрифт, несколько отличающийся от Elad.

В моих сериализуемых объектах данных я скрываю ([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);
    }
}

Ответ 4

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

Ответ 5

Попробуйте использовать 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());