Click here to Skip to main content
15,881,852 members
Articles / Desktop Programming / Windows Forms

Fully customizable Menu-, Tool-, ContextMenu-, and Status strips

Rate me:
Please Sign up or sign in to vote.
4.81/5 (19 votes)
3 Mar 2010CPOL4 min read 56.9K   3.3K   60   9
Change the colors used to render Menu-, Tool,- ContextMenu-, and Status strip controls during design-time.

imgRed.jpg

Introduction

As you may or may not know, the MenuStrip, ToolStrip, ContextMenuStrip, and StatusStrip controls (hereafter called 'Strips' or 'Strip controls', for short) can be customized to a great extent. They use the ToolStrip(Professional)Renderer class to render themselves, and it is possible to inherit this class and override the painting behavior. Of course, it takes a little effort to do that, as you are basically writing the drawing code manually.

If all you want is to change the colors of any of the Strip controls, but keep the shapes of everything (rectangular buttons, etc.), then there is a quicker way. The constructor of the ToolStripProfessionalRenderer accepts a ProfessionalColorTable, which is like a theme for the Strip controls. When supplied with a ProfessionalColorTable, the ToolStripProfessionalRenderer paints itself using the colors as specified in the ProfessionalColorTable.

While that is a much quicker way to customize your Strip controls, it still forces you to write code (inherit the ProfessionalColorTable class and override all color properties, returning your own values). These controls were designed to let you customize the colors of any of the Strip controls very easily, in the Visual Studio designer, without having to write a single line of code.

Furthermore, you change the colors in a component that can be re-used by as many Strip controls as you like. So, if you need a MenuStrip and a ToolStrip to look the same, you don't need to change their colors separately. You change the colors of this component, and they will use the same colors.

Also, your custom color definitions can be saved and loaded to and from XML files, so you can even distribute them to friends or coworkers.

Finally, there are 6 presets available that you simply have to choose from the list. The colors will then be set to mimic the colors for:

  • Office 2007 (blue)
  • Office 2003 Blue (default Windows XP style with Blue theme)
  • Office 2003 Silver (default Windows XP style with Silver theme)
  • Office 2003 Olive (default Windows XP style with Olive theme)
  • Office XP (default Windows Vista / Windows 7 style)
  • Office Classic (default style for Classic theme)

imgPresets.jpg

As you can see, the three default styles in Windows XP are also present, so you can even use the Silver theme in a Windows XP environment with a Blue theme.

Background

I made this as a project for myself. I thought it was odd that the .NET Framework provides the ability to customize the Strip controls, but doesn't provide it to the average user (e.g.: in the form of properties). I started out with a simple MenuStrip control that provided the colors via properties, but as there are so many, the properties list became very long and unwieldy. It was also a problem that you had to set the colors a second time (on the ToolStrip) when you wanted it to look the same. Or, even more times if you need more Strip controls. In short: it was still impractical.

With these controls, you only need to set the colors once, using properties in simple categories, and you can apply that theme to any Strip control you like.

Using the code

You don't need to write a single line of code to use these controls. All that is required are the following actions:

  • Build the project containing the files.
  • Drag an AppearanceControl (found in the toolbox after building) to your form.
  • Drag one or more Strip controls (found in the toolbox after building) to your form.
  • Set the Appearance property of the Strip controls to the AppearanceControl component on your form (use the dropdown in the property grid).
  • Explore the properties of the AppearanceControl. Use the Preset property to set a preset theme, or use the CustomAppearance property to change the colors manually.
  • In the Appearance Editor window that pops up, find the color property you need and change it. View the result instantly in the preview Strips.

imgEditor.jpg

Note: for the Strips to use the colors as defined in CustomAppearance, the Preset property must be set to Custom.

Points of interest

How does it work?

The AppearanceControl component uses an instance of a class that inherits ProfessionalColorTable internally. Instead of returning hardcoded values, it returns the colors as set in the CustomAppearance property:

VB
Public Class CustomColorTable _
             Inherits ProfessionalColorTable

    Private ac As AppearanceControl = Nothing

    Public Sub New(ByVal appearanceControl As AppearanceControl)
        ac = appearanceControl
    End Sub

    Overrides ReadOnly Property ButtonSelectedHighlight() As Color
        Get
            Return ac.CustomAppearance.ButtonAppearance.SelectedAppearance.Highlight
        End Get
    End Property

    Overrides ReadOnly Property ButtonSelectedHighlightBorder() As Color
        Get
            Return ac.CustomAppearance.ButtonAppearance.SelectedAppearance.BorderHighlight
        End Get
    End Property

    '...
End Class

In addition to this CustomColorTable class, there is a ColorTable for every preset which does use hardcoded color values.

The AppearanceControl exposes a ToolStripProfessionalRenderer, which has its ColorTable set to one of the internal color table classes.

Finally, the Strip controls (CustomizableMenuStrip, CustomizableToolStrip, CustomizableContextMenuStrip, and CustomizableStatusStrip) listen for a change in their AppearanceControl. When the Appearance property is set, they change their renderer from the default renderer to the Renderer property exposed by the AppearanceControl.

VB
Protected Overridable Sub OnAppearanceControlChanged(ByVal e As EventArgs)
    If Me.Appearance IsNot Nothing Then
        AddHandler Me.Appearance.AppearanceChanged, _
                   AddressOf AppearanceControl_AppearanceChanged
        AddHandler Me.Appearance.Disposed, _
                   AddressOf AppearanceControl_Disposed
        Me.Renderer = Me.Appearance.Renderer
    Else
        Me.Renderer = New ToolStripProfessionalRenderer()
    End If
    Me.Invalidate()

    RaiseEvent AppearanceControlChanged(Me, e)
End Sub

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
MarkTX26-Aug-13 10:57
MarkTX26-Aug-13 10:57 
GeneralMy vote of 5 Pin
csharpbd26-Aug-13 10:50
professionalcsharpbd26-Aug-13 10:50 
GeneralMy vote of 5 Pin
Mazen el Senih21-May-12 4:48
professionalMazen el Senih21-May-12 4:48 
GeneralImpressive work ! Pin
Mazen el Senih21-May-12 4:45
professionalMazen el Senih21-May-12 4:45 
QuestionHelp plz! Pin
Daniel Betancourt7-Mar-12 14:47
Daniel Betancourt7-Mar-12 14:47 
QuestionNavigationBar Pin
dherrmann14-Oct-11 13:05
dherrmann14-Oct-11 13:05 
RantThank you Pin
Pouriya Ghamary22-Mar-10 1:35
Pouriya Ghamary22-Mar-10 1:35 
GeneralGreat example - making the most of the Menustrip et al. Pin
simon.henson@acciobiz.com9-Mar-10 8:05
simon.henson@acciobiz.com9-Mar-10 8:05 
GeneralRe: Great example - making the most of the Menustrip et al. Pin
NickThissen9-Mar-10 8:09
NickThissen9-Mar-10 8:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.