August 23, 2006

Using FontInfo in a Custom Server Control

In many circumstances it's appropriate to assign a FontInfo structure as part of a custom server control. This easily allow programmers to adjust the look at feel of certain areas of text but can be a little tricky to implement because FontInfo doesn't have a public constructor. One way to accomplish this is to create a CSS Style object and use it's Font property to do the dirty work. This technique would look something like this:
private Style _headerFontStyle;

[Bindable(true),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
Category("Appearance"),
Description("The font for the header."),
Localizable(true)]
public FontInfo HeaderFont
{
get
{
if (_headerFontStyle == null)
{
_headerFontStyle = new Style();
}
return _headerFontStyle.Font;
}
set
{
_headerFontStyle.Font.CopyFrom(value);
}
}

So is that all there is to it? Well, not exactly. Unfortunately, FontInfo is not serializable, nor does it implement IStateManager making it difficult for us to track it's state if any changes are programmatically made to the structure.

The good news is that in the code above we're using a Style object to get at the underlying FontInfo. Since Style implements IStateManager we can override the following methods to make sure that the FontInfo property is always kept in ViewState across post backs.

protected override object SaveViewState()
{
object[] state = new object[2];
state[0] = base.SaveViewState();
state[1] = ((IStateManager)_headerFontStyle).SaveViewState();
return state;
}

protected override void LoadViewState(object savedState)
{
object[] state = (object[])savedState;
base.LoadViewState(state[0]);
((IStateManager)_headerFontStyle).LoadViewState(state[1]);
}

protected override void TrackViewState()
{
base.TrackViewState();
if (_headerFontStyle != null)
{
((IStateManager)_headerFontStyle).TrackViewState();
}
}

No comments: