Click here to Skip to main content
15,860,972 members
Articles / Mobile Apps / Windows Mobile

Creating Transparent Controls in .NET Compact Framework

Rate me:
Please Sign up or sign in to vote.
4.32/5 (11 votes)
9 Oct 2009CPOL3 min read 99K   3.4K   45   25
This article explains how to create transparent controls in .NET Compact Framework

Introduction

.NET Compact Framework doesn't provide out-of-box controls with transparent background. This article shows how to create user controls to overcome this issue.

Background

In a recent .NET compact framework application I was working on, I needed to add an image to the form's background. I did it by using the code from this video tutorial from Microsoft. However, the video also told us that the label control (and other controls) in .NET compact framework doesn't support transparent background. You will have to create your own user control. I found a good article Creating gradient background with transparent labels in .NET Compact Framework by Per Ola Sæther. It helped me to create my solution.

Using the Code

The basic ideas to create a transparent control is to override the OnPaintBackgound method of the control so it calls the parent form's OnPaintBackgound to draw the background and then draw content of the control on top of it.

In that article, the author showed how to create a transparent label control. But the code can be simplified. I also did some refactoring work so it extends to not just label control.

First, I created the same interface introduced in that article.

C#
public interface IPaintControl
{
    // have the background painted
    void InvokePaintBackground(PaintEventArgs e);
}

Then I created a base form so I don't have to write the same code for each form.

C#
public class CcForm : Form, IPaintControl
{
    public virtual void InvokePaintBackground(PaintEventArgs e)
    {
        OnPaintBackground(e);
    }
}

A base control is created so we can have not only the transparent label, but also other kinds of controls, such as radio button and checkbox. It has a property called TransparentBackground. If you don't want your control to be transparent for some reason, you can change this property. In the OnPaintBackground method, it calls its parent’s InvokePaintBackground to draw the background.

C#
public class CcTransparentControl : Control
{
    private bool _transparentBackgound = true;
    public bool TransparentBackground
    {
        get
        {
            return _transparentBackgound;
        }
        set
        {
            _transparentBackgound = value;
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        if (_transparentBackgound)
        {
            IPaintControl parent = Parent as IPaintControl;
            if (parent != null)
            {
                parent.InvokePaintBackground(e);
            }
        }
        else base.OnPaintBackground(e);
    }
}

Now we can create the transparent label control using the following code:

C#
public class CcTransparentLabel : CcTransparentControl
{
    private ContentAlignment textAlign = ContentAlignment.TopLeft;
    public ContentAlignment TextAlign
    {
        get
        {
            return textAlign;
        }
        set
        {
            textAlign = value;
        }
    }

    public CcTransparentLabel()
    {

    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics gfx = e.Graphics;
        if (this.TextAlign == ContentAlignment.TopLeft)
        {
            gfx.DrawString(this.Text, this.Font,
            new SolidBrush(this.ForeColor), ClientRectangle);
        }
        else if (this.TextAlign == ContentAlignment.TopCenter)
        {
            SizeF size = gfx.MeasureString(this.Text, this.Font);
            int left = this.Width / 2 - (int)size.Width / 2;
            var rect = new Rectangle(ClientRectangle.Left + left,
            ClientRectangle.Top, (int)size.Width,
            ClientRectangle.Height);
            gfx.DrawString(this.Text, this.Font,
            new SolidBrush(this.ForeColor), rect);
        }
        else if (this.TextAlign == ContentAlignment.TopRight)
        {
            SizeF size = gfx.MeasureString(this.Text, this.Font);
            int left = this.Width - (int)size.Width + this.Left;
            var rect = new Rectangle(ClientRectangle.Left + left,
            ClientRectangle.Top, (int)size.Width,
            ClientRectangle.Height);
            gfx.DrawString(this.Text, this.Font,
            new SolidBrush(this.ForeColor), rect);
        }
    }
}

In our form, we change the form to inherit from CcForm and drag/drop a CcTransparentLabel onto it.

C#
public partial class FormWithSolidColorBackground : CcForm

Here is the screen shot. As you can see, the label has transparent background now.

However, when I tried to add image background with gradient color, my label doesn't look right anymore.

To understand the issue, we need to first take a look at how we display background image on a form.

C#
public partial class FormWithImageBackground : CcForm
{
    private Rectangle _backgroundRect;
    private Bitmap _background;
    private string currentPath = Path.GetDirectoryName
	(Assembly.GetExecutingAssembly().GetName().CodeBase.ToString());

    public FormWithImageBackground()
    {
        InitializeComponent();

        _background = new Bitmap(currentPath + @"\ImageBackground.jpg");
        _backgroundRect = new Rectangle(0, 0, _background.Width, _background.Height);
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.DrawImage(_background, this.ClientRectangle, 
			_backgroundRect, GraphicsUnit.Pixel);
    }
}

What happened is when the OnPaintBackground was called by the transparent label control, it re-draws the image inside of the label control. So it shows the top-left corner of the image on the label’s background. To fix this issue, I pass in the location of the label control to the form and use it to re-draw the image. For example, if the label is located at (10, 20), the image background would be displayed at (-10, –20). This may not be the best solution, but it is simple and it worked. Here is the revised interface and controls.

C#
public interface IPaintControl
{
    // have the background painted
    void InvokePaintBackground(PaintEventArgs e, Point location);
}
 
public class CcForm : Form, IPaintControl
{
    public virtual void InvokePaintBackground(PaintEventArgs e, Point location)
    {
        OnPaintBackground(e);
    }
}
 
public class CcTransparentControl : Control
{
    ....
    protected override void OnPaintBackground(PaintEventArgs e)
    {
        if (_transparentBackgound)
        {
            IPaintControl parent = Parent as IPaintControl;
            if (parent != null)            
            {
                parent.InvokePaintBackground(e, this.Location);
            }
        }
        else base.OnPaintBackground(e);
    }
}

In the form, I then override the InvokePaintBackground method to draw the image at the desired location.

C#
public override void InvokePaintBackground
	(System.Windows.Forms.PaintEventArgs e, System.Drawing.Point location)
{
    Graphics g = e.Graphics;
    Rectangle destRect = new Rectangle(-1 * location.X, -1 * location.Y, 
			ClientRectangle.Width, ClientRectangle.Height);
    g.DrawImage(_background, destRect, _backgroundRect, GraphicsUnit.Pixel);
}

Now we have a transparent label over image background.

I also created a transparent radio button and checkbox controls. These are the controls commonly used in a form and so is the Panel control. The following example showed the transparent radio button and checkbox on a transparent panel.

Happy programming!

History

  • 8th October, 2009: Initial post
  • 9th October, 2009: Article updated

License

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


Written By
Team Leader www.dotnetideas.com
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionBetter Label Pin
Daniel Romero19-Oct-12 4:29
Daniel Romero19-Oct-12 4:29 
Questioni want to create tabcontrol Pin
sherif4c_sharp25-Apr-11 4:35
sherif4c_sharp25-Apr-11 4:35 
GeneralMy vote of 3 Pin
driffter3-Nov-10 1:56
driffter3-Nov-10 1:56 
QuestionExcese me , I want know something about panel,can you help me? Pin
lrt_no121-Jan-10 19:23
lrt_no121-Jan-10 19:23 
AnswerRe: Excese me , I want know something about panel,can you help me? Pin
DotNetIdeas22-Jan-10 6:02
DotNetIdeas22-Jan-10 6:02 
GeneralRe: Excese me , I want know something about panel,can you help me? Pin
lrt_no122-Jan-10 15:22
lrt_no122-Jan-10 15:22 
GeneralRe: Excese me , I want know something about panel,can you help me? Pin
DotNetIdeas23-Jan-10 15:23
DotNetIdeas23-Jan-10 15:23 
GeneralRe: Excese me , I want know something about panel,can you help me? Pin
lrt_no124-Jan-10 21:15
lrt_no124-Jan-10 21:15 
GeneralWant to draw transparent control on top of a label Pin
telll_me_morely23-Oct-09 9:43
telll_me_morely23-Oct-09 9:43 
GeneralRe: Want to draw transparent control on top of a label Pin
DotNetIdeas27-Oct-09 9:34
DotNetIdeas27-Oct-09 9:34 
GeneralRe: Want to draw transparent control on top of a label Pin
telll_me_morely28-Oct-09 7:42
telll_me_morely28-Oct-09 7:42 
GeneralRe: Want to draw transparent control on top of a label Pin
DotNetIdeas28-Oct-09 8:38
DotNetIdeas28-Oct-09 8:38 
GeneralRe: Want to draw transparent control on top of a label Pin
telll_me_morely2-Nov-09 10:08
telll_me_morely2-Nov-09 10:08 
GeneralRe: Want to draw transparent control on top of a label Pin
DotNetIdeas3-Nov-09 8:55
DotNetIdeas3-Nov-09 8:55 
GeneralRe: Want to draw transparent control on top of a label Pin
telll_me_morely5-Nov-09 8:09
telll_me_morely5-Nov-09 8:09 
GeneralRe: Want to draw transparent control on top of a label Pin
DotNetIdeas5-Nov-09 15:32
DotNetIdeas5-Nov-09 15:32 
GeneralMy vote of 1 Pin
DanWalker9-Oct-09 10:28
DanWalker9-Oct-09 10:28 
GeneralCan you give more specific reason? Pin
DotNetIdeas12-Oct-09 4:12
DotNetIdeas12-Oct-09 4:12 
GeneralRe: Can you give more specific reason? Pin
CalifBreton12-Oct-09 12:22
CalifBreton12-Oct-09 12:22 
GeneralRe: Can you give more specific reason? [modified] Pin
DotNetIdeas13-Oct-09 4:25
DotNetIdeas13-Oct-09 4:25 
GeneralRe: Can you give more specific reason? Pin
telll_me_morely28-Oct-09 7:41
telll_me_morely28-Oct-09 7:41 
GeneralJust a little correction... Pin
Paw Jershauge9-Oct-09 3:45
Paw Jershauge9-Oct-09 3:45 
GeneralThans for the correction. Pin
DotNetIdeas9-Oct-09 5:02
DotNetIdeas9-Oct-09 5:02 
GeneralRe: Thans for the correction. Pin
Paw Jershauge9-Oct-09 22:20
Paw Jershauge9-Oct-09 22:20 
GeneralGood stuff Pin
Dr.Luiji8-Oct-09 20:54
professionalDr.Luiji8-Oct-09 20: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.