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