preload
May 05

A few days ago I wanted to create a fresher UI then what .NET Compact Framework offers out of the box. I wanted to create a gradient background for the screen and I wanted to have transparent labels on top of the background. In my opinion this is not much to ask for and I was a bit surprised that I actually had to do this myself.

Well after a few hours I made a gradient background and a transparent label. I will now step by step go through my solution.

The first thing I started with was to create a gradient background. I found that the best way achieving this would be to override OnPaintBackground in the Screen class. I found a very good article on how to do this on MSDN: How to display a gradient fill. I copied the GradientFill class and the Win32Helper class into my project, I didn’t bother using the GradientFilledButton class since I only needed gradient for my background.

Then I override the OnPaintBackground in my Screen, giving me this Form:

  1. using System.Drawing;
  2. using System.Windows.Forms;
  3.  
  4. namespace GradientTransparentTest
  5. {
  6.     public partial class GradientTransparentForm : Form
  7.     {
  8.         public GradientTransparentForm()
  9.         {
  10.             InitializeComponent();
  11.         }
  12.  
  13.         // Paints the background of the form with a GradientFill pattern.
  14.         protected override void OnPaintBackground(PaintEventArgs e)
  15.         {
  16.             GradientFill.Fill(
  17.             e.Graphics, ClientRectangle,
  18.             Color.Silver, Color.LightBlue,
  19.             GradientFill.FillDirection.LeftToRight);
  20.             e.Graphics.Dispose();
  21.         }
  22.     }
  23. }

This is what my simple Form with Gradient background looks like

gradient background

OK, we now have a gradient background without having to do too much work. Lets have a look at how we can create a transparent label to put on top of our gradient background.

I created a TransparentLabel.cs which extends Control and uses the original Label control. This means that you can add a label in the designer and give it the needed properties and set it to visible=false. TransparentLabel will use the properties from the Label in OnPaint.

This is what my TransparentLabel.cs looks like now:

  1. using System.Drawing;
  2. using System.Windows.Forms;
  3.  
  4. namespace GradientTransparentTest
  5. {
  6.     public class TransparentLabel : Control
  7.     {
  8.         private Label label;
  9.  
  10.         public TransparentLabel(Label label)
  11.         {
  12.             this.label = label;
  13.             Bounds = label.Bounds;
  14.             Location = label.Location;
  15.             ClientSize = label.ClientSize;
  16.         }
  17.  
  18.         protected override void OnPaint(PaintEventArgs e)
  19.         {
  20.             Graphics gfx = e.Graphics;
  21.             if (label.TextAlign == ContentAlignment.TopLeft)
  22.             {
  23.                 gfx.DrawString(label.Text, label.Font,
  24.                 new SolidBrush(label.ForeColor), ClientRectangle);
  25.             }
  26.             else if (label.TextAlign == ContentAlignment.TopCenter)
  27.             {
  28.                 SizeF size = gfx.MeasureString(label.Text, label.Font);
  29.                 int left = label.Width/2 - (int) size.Width/2;
  30.                 var rect = new Rectangle(ClientRectangle.Left + left,
  31.                 ClientRectangle.Top, (int) size.Width,
  32.                 ClientRectangle.Height);
  33.                 gfx.DrawString(label.Text, label.Font,
  34.                 new SolidBrush(label.ForeColor), rect);
  35.             }
  36.             else if (label.TextAlign == ContentAlignment.TopRight)
  37.             {
  38.                 SizeF size = gfx.MeasureString(label.Text, label.Font);
  39.                 int left = label.Width - (int) size.Width + label.Left;
  40.                 var rect = new Rectangle(ClientRectangle.Left + left,
  41.                 ClientRectangle.Top, (int) size.Width,
  42.                 ClientRectangle.Height);
  43.                 gfx.DrawString(label.Text, label.Font,
  44.                 new SolidBrush(label.ForeColor), rect);
  45.             }
  46.         }
  47.  
  48.         // Override this method with no code
  49.         // to enable transparent background
  50.         protected override void OnPaintBackground(PaintEventArgs e)
  51.         {
  52.         }
  53.     }
  54. }

Then you add a original Label to your Form by using the designer. Remember to set the Label to visible=true. You now need to create the TransparentLabel with the Label as a parameter in your Form. I added the code below in the constructor right after InitializeComponents() in my GradientTransparentForm.cs

  1. TransparentLabel transparentLabel = new TransparentLabel(lbTransparent);
  2. Controls.Add(transparentLabel);

I was happy with my code and ran the application, but do you know what? The TransparentLabel had become a bit too much transparent. When overriding the OnPaintBackground with no code the gradient background was not drawn under where I had placed my TransparentLabel. I tried to Invalidate, Update and Refresh the background, but it still didn’t work

You can see that in the area I placed my TransparentLabel the time from my OS home screen are showing

transparent label

Bummer! I still had some work left. I found that I actually had to Invoke the OnPaintBackground (the gradient drawing). So I made a simple Interface called IPaintControl. I found the tips about invoking OnPaintBackground from the MSDN forum were Michael Koster (MVP) showed an example on this.

  1. using System.Windows.Forms;
  2.  
  3. namespace GradientTransparentTest
  4. {
  5.  
  6.     // External paint control interface
  7.     public interface IPaintControl
  8.     {
  9.         // have the foreground painted
  10.         void InvokePaint(PaintEventArgs e);
  11.  
  12.         // have the background painted
  13.         void InvokePaintBackground(PaintEventArgs e);
  14.     }
  15. }

Then I implemented IPaintControl in GradientTransparentForm and added the two required methods.

  1. public partial class GradientTransparentForm : Form, IPaintControl
  2. .
  3. .
  4. .
  5.     public void InvokePaint(PaintEventArgs e)
  6.     {
  7.         OnPaint(e);
  8.     }
  9.  
  10.     public void InvokePaintBackground(PaintEventArgs e)
  11.     {
  12.         OnPaintBackground(e);
  13.     }

In TransparentLabel I will now force drawing of the Form background in OnPaintBackground using the IPaintControl interface

  1. // Override this method invoking the parents' OnPaintBackground
  2. // to enable transparent background
  3. protected override void OnPaintBackground(PaintEventArgs e)
  4. {
  5.     IPaintControl parent = (IPaintControl)Parent;
  6.     if (parent != null)
  7.     {
  8.         parent.InvokePaintBackground(e);
  9.     }
  10. }

Finally I had my transparent label, looking like this:transparent label2

I don’t know if this is the easiest way to do this, but it works great for me. I will now continue developing my application, happily using gradient and transparent labels :)

You can download my GradientTransparentTest project with all the source code needed. Click here to get the project as a .zip file (Visual Studio 2008 project)

You can subscribe to my comments feed to keep track of new comments.

5 Comments to “Creating gradient background with transparent labels in .NET Compact Framework”

  1. Hiren says:

    Thanks. It helps me lot.

  2. Hiren,
    I’m glad you found this useful.

  3. Bjorn says:

    Thanks for sharing your code. I’m currently working on a application for WM, and I will use your lines when creating my gradients. I hope this isn’t any problem. Thanks again.

  4. Bjorn: Feel free to use any code lines you find on this blog as if they were your own. Good luck on your WM app :)

  5. VJ says:

    Very good, was searching for this stuff since last two weeks. Thanks for sharing the article as well as code.

No Pingbacks to “Creating gradient background with transparent labels in .NET Compact Framework”

Leave a Reply

Subscribe to my comments feed

Subscribe to my feeds Follow me on Twitter
Add to Technorati Favorites