Introduction

This article describes how to create a custom vertical label user control in C# .NET. The user control provides text draw from top or from bottom. This article is a derivation of Raman Tayal's Vertical Label Control in VB.NET. I just translated his work to C# and added the functionality of drawing text starting from bottom to top. Also, an updated version now supports transparent backgrounds.

Background

On one of my projects, I needed a label control that can display text vertically. I encountered Raman Tayal's Vertical Label Control in VB.NET and translated it to C#. But, I needed additional functionality of drawing text starting from the top, so I just added the functionality. This control has been useful to me, and I hope others would find it useful too.

Using the Code

The code provided is a class that creates a DLL that can be added as an item in the Toolbox of the Windows Forms designer. The class uses the following namespaces:

using System;
using System.ComponentModel;
using System.Drawing;

Code

The part of the code that really does the job is the override for the OnPaint event.

As you can see, I have an if condition in if (this.TextDrawMode == DrawMode.BottomUp). This tells us where the control decides whether to draw the text from bottom up or from top to bottom depending on the value of the property TextDrawMode.

When the value of TextDrawMode is BottomUp, you will notice that TranslateTransform accepts values zero for the X component of the translation and the height of the control as value for Y of the translation. This tells GDI to start drawing from the bottom left of the rectangle occupied by the control.

When the value of TextDrawMode is TopBottom, you will see that TranslateTransform accepts the control's width as the X component of the translation and zero as the Y component of the translation. This tells GDI to start drawing from top right of the rectangle occupied by the control.

The TextDrawMode property is an additional property that can be set during design time and also during runtime.

In this update, please notice that I am checking for the value of the _transparentBG variable which gets its value from a public boolean property TransparentBackground. If this is set to true, notice that the Brush color is set to Color.Empty; otherwise, it uses the control's assigned Color.

Also, I made the modifications on the constructor of the VerticalLabel control to include the following line:

SetStyle(System.Windows.Forms.ControlStyles.Opaque, true);

And finally, to enable transparency, the following override was added:

On the screenshot that I have provided, the horizontally-aligned text uses a WinForms Label control. The three vertical labels were displayed in different orientation (Bottom-Up | Top-Bottom) and also with different transparency (BackgroundTransparent = true|false) settings.

Points of Interest

Since this is my first time writing a program using GDI+, I tried to do it using trial and error, but it was frustrating at first, until I found a nice article on how to use Graphics.RotateTransform.

Comments and Discussions

I have learned something from you demo,but it still can not meet my needs. Do you noticed that if we expand or make the form smaller, the control would flash a lot, which bother me a lot too, can you give me some advice. thx

I am not claiming sole ownership of this work. As mentioned in the article, this was converted from the work of Raman Tayal, and not copied from the link you provided. What can I say, "great minds think alike"

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code. *http://dotnetrandz.blogspot.com*

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

I am not sure about textboxes, but i think buttons would not be that hard to implement.

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code. *http://dotnetrandz.blogspot.com*

You can create an instance of this control at runtime, very much like when you create a normal windows form control (e.g. a Label control). Say for example, you want to add a vertical label control on your form when you click on a button, you can have something like this:

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code. *http://dotnetrandz.blogspot.com*

Hi,
I was testing the code and found that when I set the text of the control to something else, the control doesn't seem to clear the existing text and write the new text on top. What can I do if I want the control to clear the old text before writing the new one. I realised you have put Invalidate() routine in the set method, but it doesn't seem to do the job. Could you please give some insight. Thanks.

I was not able to reproduce your scenario. I was to replace the text on an added vertical label control on a window form and I did not notice that the old text was still there. I am not sure but maybe there are some other factors not related to the control that may be affecting the control's behavior. Please let me know if the issue still exists. Thanks.

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code.

I re-download the code and see try again. It seems I can re-produce the problem using verticalLabel1 and verticalLabel2, but verticalLabel3 seems to be ok. Label1 and label2 problem will go away once I select another control on the form and the control will refresh itself and the problem will go away. Could you find out whether you have the same problem? I am using Vista with VS2005 SP1. Thanks.

Thank you for your reply. I was able to reproduce your scenario just now. So silly of me to test only on the third vertical label.

I think, but I am not sure, the problem was due to the enabling of WS_EX_TRANSPARENT property of the control. Microsoft says that windows does not directly support transparent windows. More on information can be found in this KB92526[^] Article. Also you can find some details regarding the WS_EX_TRANSPARENT in this article[^] from Microsoft.

This is going to be a problem when we are going to update the text value of the control during runtime. One workaround that I see is to create the vertical label control at runtime and add it to the form programmatically. I am still looking for possible solution on this problem.

It will not be a problem when the background of the control is not transparent.

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code.

Thanks for your reply. I am currently using the control and I have to update the text during runtime. So my workaround is to hide the control, modify the text and show it again to force the redraw. Trusting the information would help others.

Thank you David. I am sure this information would be helpful to others. Not to mention me, who's just started making custom controls in winforms using C#.

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code.

Hi, I tried to support transparent background in your control by adding this code to the constructor:
SetStyle(System.Windows.Forms.ControlStyles.Opaque, true);
SetStyle(System.Windows.Forms.ControlStyles.SupportsTransparentBackColor, true);
SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);

but it don't work probably. Do you have any ideas? I even tried to add the code to the OnPaint event but it's the same like adding it to the constructor.

I tried many approach in trying to provide a transparent background and I realized that I was actually drawing a rectangle background where I shouldn't.
And lastly, add this override method in the VerticalLabel class:

Remember, your work is not yours alone. Somewhere, there are some codes written by others amongst us that depends on your work. By failing to see that you are part of their ecosystem, you are bound to break their code.

Hi,
From an old code I've written, I used the same technic to draw vertical column headers.
There is however one thing you may point at in the article : it works with anti-aliasing, which is very important in Clear-Type environment.