Click here to Skip to main content
Click here to Skip to main content

Extended Vertical Label Control in C# .NET

By , 26 Sep 2007
 

Screenshot - trans_vertical.png

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.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
    float vlblControlWidth;
    float vlblControlHeight;
    float vlblTransformX;
    float vlblTransformY;

    Color controlBackColor = BackColor;
    Pen labelBorderPen;
    SolidBrush labelBackColorBrush;

    if (_transparentBG)
    {
        labelBorderPen = new Pen(Color.Empty, 0);
        labelBackColorBrush = new SolidBrush(Color.Empty);
    }
    else
    {
        labelBorderPen = new Pen(controlBackColor, 0);
        labelBackColorBrush = new SolidBrush(controlBackColor);
    }
    
    SolidBrush labelForeColorBrush = new SolidBrush(base.ForeColor);
    base.OnPaint(e);
    vlblControlWidth = this.Size.Width;
    vlblControlHeight = this.Size.Height;
    e.Graphics.DrawRectangle(labelBorderPen, 0, 0, 
                             vlblControlWidth, vlblControlHeight);
    e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, 
                             vlblControlWidth, vlblControlHeight);
    e.Graphics.TextRenderingHint = this._renderMode;
    e.Graphics.SmoothingMode = 
               System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    
    if (this.TextDrawMode == DrawMode.BottomUp)
    {
        vlblTransformX = 0;
        vlblTransformY = vlblControlHeight;
        e.Graphics.TranslateTransform(vlblTransformX, vlblTransformY);
        e.Graphics.RotateTransform(270);
        e.Graphics.DrawString(labelText, Font, labelForeColorBrush, 0, 0);
    }
    else
    {
        vlblTransformX = vlblControlWidth;
        vlblTransformY = vlblControlHeight;
        e.Graphics.TranslateTransform(vlblControlWidth, 0);
        e.Graphics.RotateTransform(90);
        e.Graphics.DrawString(labelText, Font, labelForeColorBrush, 0, 0, 
                              StringFormat.GenericTypographic);
    }            
}

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:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x20;  // Turn on WS_EX_TRANSPARENT
        return cp;
    }
}

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.

History

  • July 27, 2007: Initial version.
  • September 27: Updated with support for transparent background.

License

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

About the Author

/randz
Software Developer (Senior) Headstrong
Philippines Philippines
Member
I am working as as a full-time Software Developer in Makati City, Philippines.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberpcs041425 Apr '12 - 3:58 
helpful,thank you
Generalvery thanksmembertalinhu23 Nov '09 - 19:25 
you project gave me very big enlighten !
very thanks!
GeneralThis is copied from another sourcememberMonkeyCat28 Jan '09 - 4:41 
This looks like you just copied the code from this article with slight modifications!Thumbs Down | :thumbsdown:
 
http://simonmcc.blogspot.com/2005/09/vertical-label-component-in-c.html[^]
GeneralRe: This is copied from another sourcemember/randz14 Mar '10 - 20:49 
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" Smile | :)
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*

NewsI have posted previously an article on this subject!!!memberHoria Tudosie6 Nov '08 - 3:58 
You may find my article here:
 
http://www.codeproject.com/KB/custom-controls/VerticalLabel.aspx[^]
 
Mad | :mad:
 
Horia Tudosie

GeneralRe: I have posted previously an article on this subject!!!mvpJohn Simmons / outlaw programmer19 Nov '08 - 15:24 
Well, this is for WinForms, and yours is a web control.
 
Why did you use the pointless angry face?
 

"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

GeneralThanksmemberSpikeAustin20 Aug '08 - 10:20 
Thanks for your post here. I found it and I am wondering can teh same be done with buttons and textboxes?
GeneralRe: Thanksmember/randz21 Aug '08 - 0:40 
Hi!
 
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*

QuestionLabel at Run-timememberAlexB4716 Nov '07 - 3:32 
Hi, how to create an instance of this control at run-time ?
Thanks.
 
Alex

AnswerRe: Label at Run-timemember/randz18 Nov '07 - 15:03 
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:
 

private void button1_Click(object sender, EventArgs e)
{
randz.CustomControls.VerticalLabel lbl = new randz.CustomControls.VerticalLabel();
lbl.BackColor = System.Drawing.SystemColors.ActiveCaption;
lbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
lbl.ForeColor = System.Drawing.SystemColors.InactiveCaption;
lbl.Location = new System.Drawing.Point(217, 12);
lbl.Name = "verticalLabel3";
lbl.RenderingMode = System.Drawing.Text.TextRenderingHint.SystemDefault;
lbl.Size = new System.Drawing.Size(57, 227);
lbl.TabIndex = 3;
lbl.Text = "runtime-created";
lbl.TextDrawMode = randz.CustomControls.DrawMode.BottomUp;
lbl.TransparentBackground = true;
 
this.Controls.Add(lbl);
}

 
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*

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 26 Sep 2007
Article Copyright 2007 by /randz
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid