Click here to Skip to main content
13,254,366 members (58,290 online)
Click here to Skip to main content
Add your own
alternative version


51 bookmarked
Posted 11 Sep 2015

ToggleSwitch Winforms Control

, 11 Sep 2015
Rate this:
Please Sign up or sign in to vote.
A ToggleSwitch that presents on/off values in a more interesting way than a standard CheckBox



So, once again, I'm publishing an article about a custom painted Winforms control. I guess I ought to change my profile name to "Control Freak"... But what the heck: I love programming custom controls! Nothing to do about that.

This time I needed a ToggleSwitch or ToggleButton - something that can show a binary On/Off Checked/Unchecked state in a more interesting way than the standard checkbox. As usual, I started checking out the existing controls, because who wants to spend a lot of time reinventing something that has already been invented??? The thing that normally happens to me also happened this time: I found existing controls that could have been so great, but was leaving me wanting in some way. The best I could find (and very good looking too at that) is this one by IKalai (here on CP of course). But I had some problems with Ikalai's control. The most important one was that it doesn't allow you to change the size of the control as you want, and I couldn't make it the size I needed for my application... :-( I really don't understand why he has chosen to impose such a strange limitation on his control!

I also found this one, which is even better looking - but alas, it is built for WPF/Silverlight, so I couldn't use it.

So i did what I so often do: I started rolling my own control. And as usual, I went completely overboard and made it much more advanced than I really needed. Instead of merely doing a control that looked as I wanted and behaved as I wanted, I was inspired by the above two articles to make a control that could be made to look in a lot of different ways. In the end I wound up with NINE different styles plus the possibility to customize those styles further - AND create own renderers to add even more styles if one should feel the need to do that.

The articles didn't just inspire me, I must admit that I even stole some ideas from them... But the code is 100% mine!

In the end - after finishing the control - I got a completely different idea. So I'm not even sure I'm going to use my ToggleSwitch in the application I created it for. But here it is, nevertheless, for the benefit of y'all to use.


Control Feature Overview

1. Basic control goodies:

The control is of course doublebuffered to minimize flicker. It is also derived from the Control class so it supports both the Anchor and Dock properties.

2. Different styles:

I planked two styles from IKalai's control and seven from the WPF control. The style is changed by merely setting the Style property to the style you want.

3. Image and text support:

You can customize the control pretty much as you like. A text or image can be inserted in each side of the control (if the selected renderer supports it). You can only have either text OR image. If you have set the image property, it will take precedence and the text property will not be used.

You can also insert an image in the button itself (again if the selected renderer supports it). I didn't implement the text option for the slider button because my judgment was that the text that could fit in the button would be so small anyway that it is of no use.

4. Other cool properties:

AllowUserChange - There may be situations where you don't want the user to be able to change the value of the control, but you don't want to disable it either. If you set AllowUserChange = false, the user cannot change the value, but you can still change it in code behind.

AnimationInterval, AnimationStep & UseAnimation - When the slider moves from one state to another, it can be animated. When UseAnimation = true, the two other values determine how fast the button moves. Generally, it is moved the number of pixels set in AnimationStep for each number of milliseconds set in AnimationInterval. If you want the button to change state immediately, just set UseAnimation = false.

GrayWhenDisabled - Determines if the control is painted in grayscale when it is disabled or retains the same look as when it is enabled.

ThresholdPercentage - Determines how far you have to drag the button before it snaps to the other side. Default is 50%, so if you pull the slider button more than halfways across the control, it will automatically snap to the other side. The percentage is always calculated from the side where the button currently resides.

ToggleOnButtonClick & ToggleOnSideClick - The user can of course always drag the slider button to change the value of the switch. But using these properties, you can also decide if the control should toggle if it is clicked by the user. If ToggleOnButtonClick = true, clicking the slider button will toggle the switch. If ToggleOnSideClick = true, you can even click the areas beside the button and get the switch to toggle. If both are true, clicking anywhere on the control will toggle it, and if both properties are false, clicking the control will have no effect at all.

5. Customizable renderers:

Each style has its own renderer. Some of the basic properties such as the image properties are so common that they can be found directly on the ToggleSwitch control. Not all renderes accept all these properties, though. But most of them do. Other properties such as colors, I've chosen to attach to the specific renderers. Because they all paint the controls in so different ways, it was hard to make general color properties in the ToggleSwitch control that would make sense in all the different scenarios.

By making the color properties part of the renderers, it's possible to customize the look of a specific style much more than it would otherwise have been. The drawback is that in order to do that, you have to create a new instance of the renderer, change the properties and assign the new renderer to the control. But it's not that hard and the demo program shows exactly how to do that.

In a future version of the control, I might consider passing the renderer instance in a RendererChanged event so that the properties can be set directly without creating a new instance first. But I thought that that was overkill for this first version.


Points of Interest

The look I originally wanted for my application was the one with the brushed metal knob. All the controls I have seen with brushed metal knobs before have done them in the same way: By embedding an image file created in PhotoShop in the resources and paint that on the surface of the control. I found a PhotoShop tutorial on how to create such an image...

But it disturbed me and my touch of Asperger. Embedding a file and painting that is not so "clean" as if you paint it directly on the control yourself.

Even with the PhotoShop tutorial, I didn't really know how to paint it in C#. I asked some people on CP, but I didn't really get much help there. Pete told me that I had to use a gradient brush - which I already knew, but I couldn't really see how i could do it anyway. So I Googled some more. I found a lot of examples on how to fill a circle with a radial gradient using a PathGradientBrush. But all of those examples showed how to make a gradient that went from the inner center of the circle to the outer border (or the other way around). And I of course needed to make a gradient that went around the inside of the circle.

It wasn't easy, but FINALLY, I found this example that does more or less what I needed:

So I started dividing the image of the metal knob into gradient pie slices and paint them one by one. That worked out, But strangely enough, I discovered that if I painted all the gradients using the actual center of the knob as center for the brushes, I didn't get the look I had expected. To get the correct look, I had to offset the center of each brush slightly. I don't know why, but I got it to work in the end, I think.

"My" painted brushed metal knob may not look EXACTLY as good as a PhotoShopped one, but I was quite pleased with the result anyway. More so that I didn't have to include resources in the control library to get it to work.



Version 1.0 (2015-09-11)

Initial release


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


About the Author

Johnny J.
Software Developer (Senior)
Sweden Sweden
Born in Copenhagen, Denmark
Have been living in Paris, France and L.A., The United States
Now live in Stockholm, Sweden

Started programming when I got my first VIC 20, and a few months later on Commodore 64. Those were the days!

Studied programming at the Copenhagen Engineering Academy

Professional console, winforms and webforms programming in Comal, x86 Assembler, Fortran, Pascal, Delphi, Visual Basic 3 through 6, Classic ASP, C# and VB.NET

I now work as Senior .NET developer building Airline Booking Systems, and have a number of projects in various states of progress to work on in the spare time...

PS: The cat on my profile is one of my three cats, Ramses. He's all white, odd-eyed, deaf and definitely the coolest cat there is!

You may also be interested in...


Comments and Discussions

Khabibb Mubarakk15-Nov-17 6:57
memberKhabibb Mubarakk15-Nov-17 6:57 
QuestionToggleswitch in contextmenu Pin
Member 1136235828-Sep-17 10:03
memberMember 1136235828-Sep-17 10:03 
Questionhow do I add this winforms control to Visual Studio 2015?? Pin
prototype08155-Sep-17 3:57
memberprototype08155-Sep-17 3:57 
AnswerRe: how do I add this winforms control to Visual Studio 2015?? Pin
Member 134399432-Oct-17 4:51
memberMember 134399432-Oct-17 4:51 
QuestionNice! Where is the best place to add a OnBeforeCheckChanged cancelable event? Pin
Memetican6-Aug-17 19:40
memberMemetican6-Aug-17 19:40 
QuestionHaving Problems with download. Pin
Toadcode17-Jul-17 14:14
memberToadcode17-Jul-17 14:14 
AnswerRe: Having Problems with download. Pin
Johnny J.18-Jul-17 1:54
professionalJohnny J.18-Jul-17 1:54 
QuestionGreat control - only localizablility was missing Pin
Heinz Kessler27-Jun-17 20:57
memberHeinz Kessler27-Jun-17 20:57 
AnswerRe: Great control - only localizablility was missing Pin
Johnny J.27-Jun-17 22:40
professionalJohnny J.27-Jun-17 22:40 
PraiseThank You!! Pin
Apopka_Pilot15-Jun-17 0:46
memberApopka_Pilot15-Jun-17 0:46 
Questionhow to use them Pin
Member 1321839423-May-17 9:13
memberMember 1321839423-May-17 9:13 
QuestionHow to rotate these user controls in vertical direction Pin
guruece2413-Apr-17 2:28
memberguruece2413-Apr-17 2:28 
AnswerRe: How to rotate these user controls in vertical direction Pin
Johnny J.17-Apr-17 9:31
professionalJohnny J.17-Apr-17 9:31 
QuestionSuper control - Vote 5 - Problem with mouse click event Pin
Member 1171712610-Apr-17 10:41
memberMember 1171712610-Apr-17 10:41 
BugValidating event handler not invoked even when CausesValidation=true Pin
DEGT22-Sep-16 8:22
memberDEGT22-Sep-16 8:22 
GeneralRe: Validating event handler not invoked even when CausesValidation=true Pin
Johnny J.22-Sep-16 22:26
professionalJohnny J.22-Sep-16 22:26 
PraiseAsynchronous update? Pin
DEGT22-Sep-16 7:35
memberDEGT22-Sep-16 7:35 
GeneralRe: Asynchronous update? Pin
Johnny J.22-Sep-16 22:21
professionalJohnny J.22-Sep-16 22:21 
GeneralRe: Asynchronous update? Pin
DEGT10-Aug-17 11:37
memberDEGT10-Aug-17 11:37 
SuggestionAdd to not send CheckChanged event, if user manual change the check value Pin
Member 99037471-Aug-16 16:54
memberMember 99037471-Aug-16 16:54 
GeneralRe: Add to not send CheckChanged event, if user manual change the check value Pin
Johnny J.1-Aug-16 20:59
professionalJohnny J.1-Aug-16 20:59 
GeneralRe: Add to not send CheckChanged event, if user manual change the check value Pin
yurtan3-Jul-17 3:16
memberyurtan3-Jul-17 3:16 
QuestionHow to change the colours like in the Special Customizations tab? Pin
Member 1255315329-May-16 9:25
memberMember 1255315329-May-16 9:25 
AnswerRe: How to change the colours like in the Special Customizations tab? Pin
Johnny J.29-May-16 21:36
professionalJohnny J.29-May-16 21:36 
GeneralRe: How to change the colours like in the Special Customizations tab? Pin
Member 1255315331-May-16 13:54
memberMember 1255315331-May-16 13:54 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171114.1 | Last Updated 11 Sep 2015
Article Copyright 2015 by Johnny J.
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid