There are several articles on the web bemoaning the failure of the .NET
Tab control to Theme properly. Some of these mention that the
CheckBox control, among others, does not draw its background correctly when used on the tab control. The core of the problem for the checkbox is that it does not properly support transparency.
This article addresses this issue and adds transparency support to the
CheckBox control. Additionally, it makes the control draw in XP Style, when the
FlatStyle is set to
FlatStyle.Standard, even on older platforms that don't support themes.
Reproducing the problem
The problem itself is easy to reproduce. While there is no problem using transparency on the
CheckBox in simple applications, as soon as you start to control painting of controls yourself, for example, to add a gradient fill to a form, the problems start! See for yourself.
Create a new Windows Application Project and drop the standard .NET
CheckBox onto the
Form1 that Visual Studio creates for you.
Now, add the following code to give the form a gradient filled background:
protected override void OnPaintBackground(
= new System.Drawing.Drawing2D.LinearGradientBrush(
Protected Overrides Sub OnPaintBackground( _
ByVal e As System.Windows.Forms.PaintEventArgs)
Dim brush As New System.Drawing.Drawing2D.LinearGradientBrush( _
As you can see, the
CheckBox picks up the
BackColor of the control behind it, in this case the
Form, and not the gradient fill you painted. You can't remedy this by setting the
Transparent as the control does not support it.
The Solution, Stage 1
At first, all seemed easy. If you subclass the
CheckBox control and set the
SupportsTransparentBackColor style bit to
true, it becomes possible to set the
Transparent and all seems fine. The subclass looks like this:
public class MyCheckBox : CheckBox
public MyCheckBox(): base()
Public Class MyCheckBox : Inherits CheckBox
Public Sub New()
A few quick tests, changing the
FlatStyle proves this to work fine for
FlatStyle.System now displays a white background, even with themes enabled!
This may be sufficient for many of you, but the next stage deals with this problem as well.
The Final Solution
In the end, the only solution proved to lie in taking over the drawing of the check mark completely. It was necessary to hide the
FlatStyle from the base class, and when it appears to be set to
FlatStyle.System, set the base class property to
FlatStyle.Standard and subvert the painting of the control. In fact, the standard check mark does draw underneath, but my custom check mark draws over the top.
In keeping with the way in which the .NET
CheckBox control manages its drawing, I created a helper class to draw the check mark in a specified position. The colors are then provided by a third class that supplies the correct color set for the current theme by calling the Windows uxTheme.Dll to find out what the current theme is. If themes are not supported (Pre Windows XP), the color class returns the Blue theme colors, so you could use this to give your non themed apps the themed look and feel.
One side effect of calling the uxTheme.dll is that the UnManaged Code Access Security permission is required. Thankfully, I was able to avoid a stack walk at run time, however, the permission is required at JIT compile time. Normally, this is not an issue. However, you will find that you cannot use this control from a network share without fiddling with your .NET Security Configuration. However, this is the same problem you would have if you tried to use any other control set from a network share as all the decent ones call Unmanaged code at some point, and in fact, so many things are not possible in this configuration that it is advisable to run all .NET apps from a local drive.
On the plus side, my control actually themes better than the default .NET
CheckBox control, as the color of the check mark border does not vary with the themes in the .NET control, whereas my control sets the check mark border to the same color as the font color used in the expander panel headers of the Explorer bar shown on the left of the My Computer view of Windows Explorer. I chose this as the colors match for the default (Blue) theme and I think it is an improvement.
Aside from defaulting the
Transparent, and the
FlatStyle.System, I have made no changes to the default action of this customization of the
CheckBox control. In my personal version, I have defaulted the text to an empty string, forced the DataBindings to persist in the designer, and added a databinding between the checked state and the font style so that the text changes to bold font when the
CheckBox is checked.
Please note that the control does not provide a view through to the windows behind when using the
TransparencyKey property. This is because I have had to set the
AllPaintingInWMPaint style bit to
true to ensure that the check mark draws correctly.
Using the control
The demo project and source code differ only in the inclusion of a Windows application project to demonstrate the difference between the
CustomCheckBox and the default
CheckBox. Both zip files contain the entire source code for the three classes required, packaged as Windows Control Projects in C#.NET and VB.NET so that you can copy the source code into your own projects.
If you wish to use the control as it is, build either Windows control project, C#.NET or VB.NET as your preference takes you, and add the control to your toolbox by selecting the resulting assembly from the Add/Remove Items dialog when customizing your Toolbox.