how to serialize font

A

Andrus

I have class

FormData {
public System.Drawing.Font TextBoxFont;
}

I need to read/store this class in isolated storage in Winforms application.

Using

XmlSerializer formatter = new XmlSerializer(typeof(FormData),
"MyNameSpace");

causes exception

System.Drawing.Font cannot be serialized because it does not have a
parameterless constructor.

How to fix ?

Andrus.
 
P

Pavel Minaev

I have class

FormData {
   public System.Drawing.Font  TextBoxFont;

}

I need to read/store this class in isolated storage in Winforms application.

Using

XmlSerializer formatter = new XmlSerializer(typeof(FormData),
"MyNameSpace");

causes exception

System.Drawing.Font cannot be serialized because it does not have a
parameterless constructor.

How to fix ?

Avoid using XmlSerializer. It's not designed to work with
arbitrary .NET classes - you pretty much to have to write classes
specifically for it. In this case, either seialize Font by hand
directly via XmlReader/XmlWriter (preferrably) or XmlDocument; or,
write your own XmlSerializer-compatible class with the same properties
as Font (or rather, those properties that are sufficient to recreate
the font), and serialize that.
 
I

Ignacio Machin ( .NET/ C# MVP )

I have class

FormData {
public System.Drawing.Font TextBoxFont;

}

I need to read/store this class in isolated storage in Winforms application.

Using

XmlSerializer formatter = new XmlSerializer(typeof(FormData),
"MyNameSpace");

causes exception

System.Drawing.Font cannot be serialized because it does not have a
parameterless constructor.

How to fix ?

Andrus.

Must probably you need to cast the Font to ISerializable
 
P

Pavel Minaev

Must probably you need to cast the Font to ISerializable

ISerializable has absolutely nothing to do with XmlSerializer - it is
used for binary and SOAP serialization only.
 
A

Andrus

Avoid using XmlSerializer. It's not designed to work with
arbitrary .NET classes - you pretty much to have to write classes
<specifically for it. In this case, either seialize Font by hand
<directly via XmlReader/XmlWriter (preferrably) or XmlDocument; or,
write your own XmlSerializer-compatible class with the same properties
as Font (or rather, those properties that are sufficient to recreate
the font), and serialize that.

I created class below and use it instead of Font class.
Is this best solution ?

Andrus.

public sealed class SerializableFont
{
// public properties are required for serialization only
public string FamilyName;
public float EmSize;

// required for serializaton only
public SerializableFont()
{
}

public SerializableFont(Font font)
{
FamilyName = font.FontFamily.Name;
EmSize = font.Size;
}

[XmlIgnore]
public Font Font
{
get
{
if (FamilyName == null || EmSize == 0)
return null;
return new Font(FamilyName, EmSize);
}
}
}
 
P

Pavel Minaev

Avoid using XmlSerializer. It's not designed to work with
arbitrary .NET classes - you pretty much to have to write classes

<specifically for it. In this case, either seialize Font by hand
<directly via XmlReader/XmlWriter (preferrably) or XmlDocument; or,
write your own XmlSerializer-compatible class with the same properties
as Font (or rather, those properties that are sufficient to recreate
the font), and serialize that.

I created class below and use it instead of Font class.
Is this best solution ?

Andrus.

    public sealed class SerializableFont
    {
        // public properties are required for serialization only
        public string FamilyName;
        public float EmSize;

        // required for serializaton only
        public SerializableFont()
        {
        }

        public SerializableFont(Font font)
        {
            FamilyName = font.FontFamily.Name;
            EmSize = font.Size;
        }

        [XmlIgnore]
        public Font Font
        {
            get
            {
                if (FamilyName == null || EmSize == 0)
                    return null;
                return new Font(FamilyName, EmSize);
            }
        }
    }

That's pretty much it, though I'd use a ToFont() method instead of
your Font property to convey the intent better - properties really
shouldn't create new objects on every gettor call; and you'll also
avoid {XmlIgnore] that way.
 
A

Andrus

That's pretty much it, though I'd use a ToFont() method instead of
your Font property to convey the intent better - properties really
shouldn't create new objects on every gettor call; and you'll also
avoid {XmlIgnore] that way.

FxCop orders to use properties instead of Getter methods. Probably ToFont()
method will be
flagged as issue by FxCop.

I noticed that Project Settings Window allows to add directly Font datatype
and store/restore its values.
Font values are serialized as string as "Arial, 12"
ComponentModel automatically uses TypeConverter to serialize fonts in this
case.

Maybe it is reasonable to use TypeConverter and avoid creating wrapper
object ?

Andrus.
 
P

Pavel Minaev

FxCop orders to use properties instead of Getter methods. Probably ToFont()
method will be
flagged as issue by FxCop.

FXCop is just plain wrong there. Have a look at the BCL classes - how
many GetXxx() methods can you find. They are usually there for a
reason. One prominent example is IEnumerable.GetEnumerator() - it is a
method, and not a property, because on every call it creates a new
enumerator. The fundamental contract of a property is that, if the
state of the system does not change, calling the property gettor twice
should return the same value (i.e., foo.Bar == foo.Bar).

And no, it will not flag ToXxx() methods - would it flag, say,
ToString()? I've no idea, to be honest, since I've last used FXCop
several years ago - but if it did that, it's just not worth using. Or
maybe you should turn off that specific rule for it...
Maybe it is reasonable to use TypeConverter and avoid creating wrapper
object ?

If you do not need to serialize individual font properties to XML in
such a way that they are clearly separated in that XML (so that they
could be described by XML Schema, and easily retrieved using XPath),
then sure, using TypeConverter to convert to/from string, and storing
that string within an XML attribute or element, is a perfectly valid
solution.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top