Introduction
This is my first article, so please bear with me on this...
Themer is a component control that allows you to easily apply a group of
settings to controls and, optionally, handle those controls' events.
Themer
comes from the idea of CSS for web pages. The basic idea is Themer can
apply it's settings to a Group, a specific control, or all controls of
a certain type. Themer uses an XML file to keep its list of theme
information. You can easily change the theme file to another file (for
example, if you want to allow the user to change the theme or skin of
your application).
How Themer Works
Themer includes a special class, clsThemeWriter
, which you can use to easily create your theme files.
Using the clsThemeWriter
,
you save a list of properties and/or events that you want to have
themed. You can set these properties to be applied to a group, control
name, or control type.
During application execution,
Themer will loop through each Control on your form. Themer will apply
the settings in the Theme file, first using Control Type (example
System.Windows.Forms.Button), then GroupName, and finally Control ID.
If nothing is found, Themer continues to the next Control on the form.
Once
a match has been found for the Control in the Theme file, Themer will
apply all property settings in the Theme file to the current Control.
Examples of settings could be Text, BackColor, ForeColor, and Size.
Next, Themer will check if any events have been registered in the Theme
file. If so, Themer will hook those events.
If you want a
control on your form to not be themed, you can use the extended
properties provided by the component control ThemerBase to specify that
a control should not implement theming.
If Themer finds a
property or event in the theme file, but the current Control does not
have this property/event, Themer will skip that property/event.
NOTE:
This control relies on Case Sensitivity. Therefore, property names,
event names, etc. must be properly capitalized when creating the theme
file.
clsThemeWriter
The clsThemeWriter
class handles all the work of creating a theme file. When you create
the class, you can pass in the location where the Theme should be
saved. You can also pass in the location of an existing Theme file, in
which case the file will simple be updated.
clsThemerWriter tw = new clsThemerWriter(@"c:\temp2\theme2.theme");
Groups, Controls, and Control Types
Theme
information can be applied to a group, a specific control, and/or all
controls of a specific type. The order of applying properties is
Control Type, GroupName, Control Name. Once a match has been found,
Themer will apply the settings from the. If you create a ControlName
setting and a GroupName setting that could both apply to ObjectX, both
settings will be applied to ObjectX.
ThemerType
This Enum specifies which setting type should be applied to this instance of the clsThemeWriter.
UseGroup
– this flag specifies that clsThemeWriter is creating a GroupName
setting. All settings in this instance will apply to all controls which
have their GroupName property set to the same value in
clsThemeWriter.GroupName - Set the GroupName property if you set the UseGroup flag
UseControlName
– this flag specifies that clsThemeWriter is creating a ControlName
setting. All settings in this instance will apply to any control whose
Name property is the same as clsThemeWriter.ControlName - Set the ControlName property if you set the UseControlName flag
UseControlType
– this flag specifies that clsThemeWriter is creating a Control Type
setting. All controls which match this Type will have their properties
updated
- Set the ControlType property if you set the UseControlType flag
- NOTE: You must use the full name of the control (including namespace), such as System.Windows.Forms.Button
PropertyList
The
list of properties for the Control(s) which should be updated. This
list is of type Themer.ThemeWriter.TWHelperItem. For each item in this
list, set the following TWHelperItem properties:
ItemName
– the name of the Control's property to update (such as Text or ForeColor). CASE SENSITIVE ItemValue
– the object value to assign to the Control's property (such as "123" or Color.Black). Must be serializable
EventList
The
list of events which should be hooked on the Control(s). This list is
of type Themer.ThemeWriter.TWHelperItem. For each item in this list,
set the following TWHelperItem properties:
ItemName
– the name of the Control's Event (such as Click or DoubleClick) TargetMethodName
– the name of the Method that will receive event notification (this is
a method you will create. This is explained in more detail in the next
section).
Saving the Theme File
Once you have created a theme item (group, control name, or control type), you need to call UpdateThemeFile
, passing in the TWHelper object. You will call UpdateThemeFile
for each theme item you want to add.
Applying a Theme to Your Form - ThemerBase
Once you have created one or more theme files, it is time to apply the theme to your form. Drop the ThemerBase
component control on your form.
New Properties Added to Form Controls
You will notice all the Controls on your form will have two new properties:
ApplyTheme
– when true, theme will be applied to this control if one is found in the theme file - When false, this Control will be skipped during theming
ThemerGroupName
– the name of the group. All Controls in a group will have the same settings applied. - Set to an empty string or GlobalGroup if you don't want the control to be in a Group.
ThemerBase Properties
ThemerBase has two properties you need to set:
ThemePath
– this is the path of the theme file. ThrowErrors
– When set to true, errors are allowed to propogate from Themer. The
few instances of errors being thrown would be, for example, an error
with the theme xml file.
- Setting this property to false will suppress most errors in Themer.
- Default is true
ThemerBase Events
When
you created the theme file, you had the option to add events to hook on
the object. To hook into the events, you need to create a special class
that will receive the events you want to hook. On the form holding the ThemerBase
control, set the EventObject
to the new class you created.
The
new class you create will contain methods as defined in the themer
file. These methods must match the delegate definition for which they
are being hooked, or an error will be raised.
For example,
if you want to hook the Click event of a button, in the themer file,
add Click to the event list (TargetMethod = "Click_Hooked", for
example). In your new class, create a method:
public void Click_Hooked (object sender, EventArgs e)
Now, when the button is clicked, Click_Hooked will be called as well.
Changing Themes
You can dynamically change the theme of your form by changing the ThemePath
. Once you have changed ThemePath
, you will need to call ThemerBase.ApplyTheme()
to implement the new theme. This allows you to give users the option to
change themes and have those changes applied immediately!
Using the code
Here is a sample project to demonstrate how you can easily change
control properties with Themer. The sample let's users choose between
two templates (Template1 and Template2). The templates are first
created, then loaded with ApplyTheme()
.
Each control is given a group name (Group1 or Group2). The button and
label belong to Group1, while the textbox and groupbox belong to Group2.
This example demonstrates how to write settings to the themer file and how to apply those settings to a form.
private void button1_Click(object sender, EventArgs e)
{
string filename = @"c:\temp2\theme1.theme";
clsThemerWriter tw = new clsThemerWriter(filename);
TWHelper twh = new TWHelper("Group1", "", "", ThemerType.UseGroup);
twh.PropertyList.Add(new TWHelperItem("Text", "Theme1 - Group1"));
twh.PropertyList.Add(new TWHelperItem("BackColor", Color.LightBlue));
tw.UpdateThemeFile(twh);
twh = new TWHelper("Group2", "", "", ThemerType.UseGroup);
twh.PropertyList.Add(new TWHelperItem("Text", "Theme1 - Group2"));
twh.PropertyList.Add(new TWHelperItem("ForeColor", Color.Purple));
tw.UpdateThemeFile(twh);
this.themerBase1.ThemePath = filename;
this.themerBase1.ApplyTheme();
}
private void cmdTheme2_Click(object sender, EventArgs e)
{
string filename = @"c:\temp2\theme2.theme.theme";
clsThemerWriter tw = new clsThemerWriter(filename);
TWHelper twh = new TWHelper("Group1", "", "", ThemerType.UseGroup);
twh.PropertyList.Add(new TWHelperItem("Text", "Theme2 - Group1"));
twh.PropertyList.Add(new TWHelperItem("BackColor", Color.LemonChiffon));
tw.UpdateThemeFile(twh);
twh = new TWHelper("Group2", "", "", ThemerType.UseGroup);
twh.PropertyList.Add(new TWHelperItem("Text", "Theme2 - Group2"));
twh.PropertyList.Add(new TWHelperItem("ForeColor", Color.Red));
tw.UpdateThemeFile(twh);
this.themerBase1.ThemePath = filename;
this.themerBase1.ApplyTheme();
}
Points of Interest
Themer
is a very versatile control. You can easily create a variety of skins
for your project and quickly change them dynamicaly as the user desires.