Introduction
This article was written to demonstrate how to customize the display of the ToolStrip
, MenuStrip
, and StatusStrip
controls. We will look at the ProfessionalColorTable
class as well as the ToolStripCustomRenderer
class.
Background
Over the past few months, I've created UIs using an MDI form. I wanted each UI to have its own custom color theme. The old Windows look starts to get old after awhile. Customizing the color schemes is fairly easy via code, but I wanted to edit the colors at design time. I also wanted something I could use over and over again.
Using the code
In my project, three different controls exist. Since each control is pretty much the same, I will just focus on the ToolStrip
control.
To begin, we need the following two things:
- A custom
ToolStrip
control
- A custom color table
To create the custom control, simply add a new user control to the project. The file we just added inherits from the UserControl
class. Instead, I want to inherit from the System.Windows.Forms.ToolStrip
class, as shown below.
public partial class CustomToolStrip : ToolStrip
The reason I start with the UserControl
is to 'steal' its InitializeComponent
method. If you attempt to compile the project after changing the inheritance, you will receive an error. We will need to remove the AutoScale
property from the InitializeComponent
method.
Next, we need to create a class that holds our color scheme information. We do this by adding a blank class. We will need to make our class inherit from System.Windows.Forms.ProfessionalColorTable
.
internal class CustomToolStripColorTable : ProfessionalColorTable
Now that we have the inheritance setup, we will need to override the methods for the colors we want to set. Listed below is what the completed class will look like (I will explain the Properties part next).
using System;
using System.Drawing;
using System.Windows.Forms;
namespace System.Windows.Forms
{
internal class CustomToolStripColorTable : ProfessionalColorTable
{
public override Color ToolStripBorder
{
get
{
return Properties.Settings.Default.ToolStripBorder;
}
}
public override Color ToolStripContentPanelGradientBegin
{
get
{
return Properties.Settings.Default.ToolStripContentPanelGradientBegin;
}
}
public override Color ToolStripContentPanelGradientEnd
{
get
{
return Properties.Settings.Default.ToolStripContentPanelGradientEnd;
}
}
public override Color ToolStripDropDownBackground
{
get
{
return Properties.Settings.Default.ToolStripDropDownBackground;
}
}
public override Color ToolStripGradientBegin
{
get
{
return Properties.Settings.Default.ToolStripGradientBegin;
}
}
public override Color ToolStripGradientMiddle
{
get
{
return Properties.Settings.Default.ToolStripGradientMiddle;
}
}
public override Color ToolStripGradientEnd
{
get
{
return Properties.Settings.Default.ToolStripGradientEnd;
}
}
}
}
As you can see, the return values are set to Properties.Settings.Default.xxxxx
. The reason I've instructed you to create the methods first is so we can copy and paste the method names into our Settings file.
Within the Properties folder in the Solution Explorer, there should be a Settings.settings file. If it does not exist, add it. Go ahead and create a setting for each color item. Each item should be of type System.Drawing.Color
. Select the default colors for each.
The reason we are creating the settings file is so that we can persist changes. To persist user changes, we need to make sure the scope is set to User rather than Application (this is read only).
Now, it is time to revisit our custom control and pull everything together. First, we need to tell the control to render from our custom color table.
#region Constructor
public CustomToolStrip()
{
InitializeComponent();
this.RenderMode = ToolStripRenderMode.Professional;
this.Renderer = new ToolStripProfessionalRenderer(
new CustomToolStripColorTable());
}
#endregion
The next step is to set the control up to be edited in design time. The following code demonstrates this task:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace System.Windows.Forms
{
public partial class CustomToolStrip : ToolStrip
{
#region Constructor
public CustomToolStrip()
{
InitializeComponent();
this.RenderMode = ToolStripRenderMode.Professional;
this.Renderer = new ToolStripProfessionalRenderer(
new CustomToolStripColorTable());
}
#endregion
#region Properties
[Category("Style")]
[DisplayName("ToolStripForeColor")]
public Color ToolStripForeColor
{
get { return Properties.Settings.Default.ToolStripForeColor; }
set
{
Properties.Settings.Default.ToolStripForeColor = value;
this.ForeColor = value;
}
}
[Category("Style")]
[DisplayName("ToolStripBorder")]
public Color ToolStripBorder
{
get { return Properties.Settings.Default.ToolStripBorder; }
set { Properties.Settings.Default.ToolStripBorder = value; }
}
[Category("Style")]
[DisplayName("ToolStripContentPanelGradientBegin")]
public Color ToolStripContentPanelGradientBegin
{
get { return Properties.Settings.Default.ToolStripContentPanelGradientBegin; }
set { Properties.Settings.Default.ToolStripContentPanelGradientBegin = value; }
}
[Category("Style")]
[DisplayName("ToolStripContentPanelGradientEnd")]
public Color ToolStripContentPanelGradientEnd
{
get { return Properties.Settings.Default.ToolStripContentPanelGradientEnd; }
set { Properties.Settings.Default.ToolStripContentPanelGradientEnd = value; }
}
[Category("Style")]
[DisplayName("ToolStripDropDownBackground")]
public Color ToolStripDropDownBackground
{
get { return Properties.Settings.Default.ToolStripDropDownBackground; }
set { Properties.Settings.Default.ToolStripDropDownBackground = value; }
}
[Category("Style")]
[DisplayName("ToolStripGradientBegin")]
public Color ToolStripGradientBegin
{
get { return Properties.Settings.Default.ToolStripGradientBegin; }
set { Properties.Settings.Default.ToolStripGradientBegin = value; }
}
[Category("Style")]
[DisplayName("ToolStripGradientMiddle")]
public Color ToolStripGradientMiddle
{
get { return Properties.Settings.Default.ToolStripGradientMiddle; }
set { Properties.Settings.Default.ToolStripGradientMiddle = value; }
}
[Category("Style")]
[DisplayName("ToolStripGradientEnd")]
public Color ToolStripGradientEnd
{
get { return Properties.Settings.Default.ToolStripGradientEnd; }
set { Properties.Settings.Default.ToolStripGradientEnd = value; }
}
#endregion
}
}
The attributes I've added (Category
, DisplayName
) are totally optional, but are nice to have when looking for the items in the designer.
To wrap things up, we can build the project, and then the custom control will show up in the toolbox. Go ahead and add the control, and edit the colors via the designer.