Introduction
We've all had that problem - designing our web sites to have a certain look and feel. Unfortunately, not every visitor will view the site the way you intended. This is due to the fact that different operating systems render native browser controls differently. The buttons in OS X have the aqua look while the buttons in Windows 2000 look gray and outdated.
Using the AnyButton
Until now, to enforce a consistent look, a popular option was using images as buttons. This is a great alternative except that when it comes to adding new buttons or modifying existing ones, you better have Photoshop [and the time] handy to get it done.
I�ve created a control called the AnyButton
which derives from System.Web.UI.WebControls.ImageButton
. This button uses image templates as skins. It will take a JPG, GIF or PNG as a template. It is really easy to use, and best of all, looks just like a real button. This control is compatible with IE6, Firefox, Netscape and Safari browsers.
The control takes in a single image as a template. The button supports three different states � default
, hover
, and press
. Moreover, each button supports three different skins � 1 for each state. This allows you to create as many types of buttons as you�d like by subclassing the base Button
class. For instance, you could have an XPButton
, AquaButton
, AmazonComButton
, etc. The best part is, you don�t have to use Photoshop to create your buttons � if you see a button on a site you like, screen shot it, crop out the middle part and you�re pretty much ready to go.
Here�s an example using the XP button as a skin:
- This is the default state template that I will assign to the button:
- This is the hover state template that I will assign to the button:
- And this is the press state template that I will assign to the button:
As you can see, the red lines dictate how to slice the button. These lines must be the exact RGB color (255, 0, 0) or #FF0000.
Each button has a ButtonConfig
class as a property. The ButtonConfig
class contains all the information about the button templates. Here's an example using all button states, generating a button that resembles the XP Silver button:
public class XPButton : AnyButton
{
public XPButton()
{
this.EnableHover = true;
this.EnablePress = true;
}
public XPButton(Page page)
{
this.Page = page;
this.EnableHover = true;
this.EnablePress = true;
}
protected override void OnInit(EventArgs e)
{
Initialize();
base.OnInit(e);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
protected void Initialize()
{
Font f = new Font("Tahoma", 8, FontStyle.Regular);
ButtonConfig buttonConfig = new ButtonConfig();
buttonConfig.TemplatePath = "~/xp_button/default.png";
buttonConfig.OutputPath = "~/output/xp";
buttonConfig.Font = f;
buttonConfig.VerticalTextOffset = 1;
buttonConfig.FontColor = Color.Black;
this.Config = buttonConfig;
ButtonConfig hoverConfig = new ButtonConfig();
hoverConfig.TemplatePath = "~/xp_button/hover.png";
hoverConfig.OutputPath = buttonConfig.OutputPath;
hoverConfig.Font = buttonConfig.Font;
hoverConfig.VerticalTextOffset = buttonConfig.VerticalTextOffset;
hoverConfig.FontColor = buttonConfig.FontColor;
this.HoverConfig = hoverConfig;
ButtonConfig pressConfig = new ButtonConfig();
pressConfig.TemplatePath = "~/xp_button/press.png";
pressConfig.OutputPath = buttonConfig.OutputPath;
pressConfig.VerticalTextOffset = buttonConfig.VerticalTextOffset + 1;
pressConfig.HorizontalTextOffset = buttonConfig.VerticalTextOffset + 1;
pressConfig.Font = hoverConfig.Font;
pressConfig.FontColor = buttonConfig.FontColor;
this.PressConfig = pressConfig;
}
}
This example is pretty straightforward. One thing to note is the VerticalTextOffset
and HorizontalTextOffset
properties being utilized in the pressConfig
. To get a true pressed effect, the text should move to the bottom right 1 pixel by 1 pixel.
This example demonstrates how to create an XP Themed button. To get you started right away, I've packaged the XPButton
along with the AnyButton assembly. I did this so you could use the AnyButton
without a template (XP), right off the bat. The three state templates for the XPButton
come embedded as part of the DLL. When the XPButton
is first called, it will need to extract out the templates to a specified path. This path is settable via the TemplateExtractPath
property. This property is unique only to the XPButton
and only used to extract its templates.
When a button deriving from AnyButton
is called, it must save these generated images to a location on disk for later use. Each state on each type of button can technically have a different output path. Most likely, the output path will be the same for all states of the button. To set the output path, use the OutputPath
property. This property will accept application-scope paths (~/). It is imperative that the ASPNET user account have read/write access to this path.
So far so good, right? Using the control is the easiest part. Have a look:
<%@ Register TagPrefix="btn" Namespace="MyNamespace" Assembly="MyAssembly" %>
<btn:XPButton Runat="server" Text="Click Me"/>
This is the result of the previous call:
As you can see, three images were created; 1 for each state. Any subsequent requests for an XPButton
with text "Click Me" will now be redirected to the already-generated button image. To clear the cache of images, simply delete the output directory.
Additional Properties:
AlphaPng
If you are using PNG files and you want to enforce transparency, set the AlphaPng
setting to true
. This is necessary because IE does not support alpha PNG (right on MS). When AlphaPng
is true
, a special CSS filter will be added only to IE users (Firefox, Safari, etc. users will not be affected).
TextWidth
Use this property when you want to enforce a certain width regardless of the actual width of the text.
OnClientClick
Handy little property that can be set in the markup adding client side function call when the button is pressed.
AntiAliasText
true
by default, applies anti-aliasing and ClearType
effect.
CausesPostback
By default, an ImageButton
(from which this control derives) is a submit button. To disable posting back, set CausesPostback
to false
.
ForceRedraw
This isn't a property, but rather a querystring variable that, when present, will force the redrawing of the buttons, ignoring cache. [Example usage: http://www.mysite.com/default.aspx?ForceRedraw=true.]
That's pretty much all there is to it.
Links