1

我有一个班级,我[Serializable]为那个班级设置了属性。

在这个类中,我定义了一个字体类成员。但是当我尝试序列化时,它给了我一个错误,比如“system.drawing.font 无法序列化”

4

3 回答 3

7

我在最近的一个项目中这样做了:

[XmlIgnore()]
public Font Font {
  get { return mFont; }
  set { mFont = value; }
}

[Browsable(false)]
public string FontHidden {
  get { return FontSerializationHelper.Serialize(mFont); }
  set { mFont = FontSerializationHelper.Deserialize(value); }
}

FontSerializationHelper 类如下:

using System.Windows.Forms;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Text.RegularExpressions;
using System.Xml.Serialization;

[TypeConverter(typeof(FontConverter))]
internal class FontSerializationHelper
{
    public static Font Deserialize(string value)
    {
        object m = Regex.Match(value, "^(?<Font>[\\w ]+),(?<Size>(\\d+(\\.\\d+)?))(,(?<Style>(R|[BIU]{1,3})))?$", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);

        if (m.Success) 
        {
            if (m.Groups.Count < 4 || m.Groups(3).Value == "R") 
            {
                return new Font(m.Groups("Font").Value, Single.Parse(m.Groups("Size").Value));
            } 
            else 
            {
                object fs = m.Groups(3).Value.IndexOf("B") >= 0 ? FontStyle.Bold : FontStyle.Regular | m.Groups(3).Value.IndexOf("I") >= 0 ? FontStyle.Italic : FontStyle.Regular | m.Groups(3).Value.IndexOf("U") >= 0 ? FontStyle.Underline : FontStyle.Regular;
                return new Font(m.Groups("Font").Value, Single.Parse(m.Groups("Size").Value), fs);
            }
        } 
        else 
        {
            throw new FormatException("Value is not properly formatted.");
        }
    }

    public static string Serialize(Font value)
    {
        string str;

        str = value.Name + "," + value.Size.ToString() + ",";
        if (value.Style == FontStyle.Regular) 
        {
            str += "R";
        } 
        else 
        {
            if (value.Bold) str += "B";
            if (value.Italic) str += "I";
            if (value.Underline) str += "U";
        }

        return str;
    }
}

请注意,我只是保存字体系列、大小和样式信息。您可能想要添加更多内容。

于 2013-10-12T14:29:46.290 回答
4

即使这个问题很老,这里是我的解决方案:

解决方案#1(这个丢失GdiCharSetGdiVerticalFont参数):

private Font font = new Font("Arial", 13f, FontStyle.Regular, GraphicsUnit.Pixel, 0, false);

[XmlIgnore()]
public Font Font {
    get { return font; }
    set { font = value; }
}

[Browsable(false)]
public string FontSerialize {
    get { return TypeDescriptor.GetConverter(typeof(Font)).ConvertToInvariantString(font); }
    set { font = TypeDescriptor.GetConverter(typeof(Font)).ConvertFromInvariantString(value) as Font; }
}

解决方案#2(利用所有 Font构造函数参数):

特性:

[XmlIgnore()]
public Font Font {
    get { return font; }
    set { font = value; }
}

[Browsable(false)]
public string FontSerialize {
    get { return FontSerializationHelper.ToString(font); }
    set { font = FontSerializationHelper.FromString(value); }
}

FontSerializationHelper 类:

[TypeConverter(typeof(FontConverter))]
static public class FontSerializationHelper {

    static public Font FromString(string value) {
        var parts = value.Split(':');
        return new Font(
            parts[0],                                                   // FontFamily.Name
            float.Parse(parts[1]),                                      // Size
            EnumSerializationHelper.FromString<FontStyle>(parts[2]),    // Style
            EnumSerializationHelper.FromString<GraphicsUnit>(parts[3]), // Unit
            byte.Parse(parts[4]),                                       // GdiCharSet
            bool.Parse(parts[5])                                        // GdiVerticalFont
        );
    }

    static public string ToString(Font font) {
        return font.FontFamily.Name
                + ":" + font.Size
                + ":" + font.Style
                + ":" + font.Unit
                + ":" + font.GdiCharSet
                + ":" + font.GdiVerticalFont
                ;
    }
}

EnumSerializationHelper 类:

[TypeConverter(typeof(EnumConverter))]
static public class EnumSerializationHelper {

    static public T FromString<T>(string value) {
        return (T)Enum.Parse(typeof(T), value, true);
    }
}
于 2016-01-21T21:11:28.477 回答
3

You can't serialize a Font. You can't serialize most GDI resources.

You can try to use the FontConverter class to serialize it to a string for you.

于 2013-10-09T04:35:11.537 回答