Of Windows Forms, Transparent Controls & Beautiful Code

How do you make an old war-horse like the Windows Forms  let you create transparent controls that new technologies like HTML5 and WPF enable ‘out-of-the-box’? By re-coding of course!

Windows forms have a special appeal to .NET developers as they have been around for ages and are very easy to code for beginners and pros alike. I started my foray into the world of .NET with windows forms and soon, I knew how to get things done. Not only was I using them at work, I was also working with them at home, just for the fun of it. This made me an expert of sorts at creating visually appealing UIs.

As I matured in programming with .NET, I encountered numerous problems with windows forms though. And one of those problems was creating transparent controls to make my UI look cool. I searched the Web to look for others who might have done it and found a few of them come up with hundreds of lines of code to create a transparent control. I found it hard to believe that this simple task would require such a huge amount of code in an advanced and popular programming language like C#! So, one fine saturday morning, I sat down to do some serious coding.

Setting Objectives

Clearing The Head

My only aim that morning was to create transparent controls that do not impact the performance of the parent form. This had to be accomplished with as little code as possible. So, I fired up Visual Studio and sat down for what I thought would be a long day.

Firstly, I created a new control in my WF project and named it CustomRTB.cs (short for Custom Rich Text Box). Next, I made changes to its partial class and overrode the control’s CreateParams property to add (after much trial and error) my custom features:

public partial class CustomRTB : RichTextBox
{
   public CustomRTB()
   {
      InitializeComponent();
   }
   protected override CreateParams CreateParams
   {
      get
      {
         //This makes the control's background transparent
         CreateParams CP = base.CreateParams;
         CP.ExStyle |= 0x20;
         return CP;
      }
   }
}

This piece of code let me create truly transparent controls without impacting the parent form’s performance and rendering capacity. It was simply beautiful – with one BIG flaw: the control could only be used to display text programmatically. That is, if you launched your application and attempted to write text in the control or scroll it, it would become a blurry mess. This was a serious problem as I wanted a transparent control which was dynamic and would allow a user to edit the text as well (if it were an editable control). But, as it turned out, it led me to create an even better control.

Achieving Heights

Heights

After much deliberation, I thought of creating another transparent wrapper control that would hold the CustomRTB. This way, the wrapper control would remain transparent and inherit the parent form’s background while the CustomRTB would inherit the wrapper control’s background, which actually, is the parent form’s background. I know – it doesn’t make sense to me either. But I went ahead with it anyway.

I created another control and named it CustomPanel.cs. I knew I couldn’t override the CreateParams property of this control as it would make no difference and the problem would persist. I had to use another approach that would not only solve the problem but also let me control the transparency as well. I wrote code, tested it, optimised it, wrote some more code and repeated the cycle. After some struggle, I arrived at a piece of code for the custom panel that ticked all the boxes of my original objective:

public partial class CustomPanel : Panel
{
   public CustomPanel()
   {
      InitializeComponent();

      //Code for a control whose transparency can be controlled
      SetStyle(ControlStyles.SupportsTransparentBackColor |
        ControlStyles.OptimizedDoubleBuffer |
        ControlStyles.AllPaintingInWmPaint |
        ControlStyles.ResizeRedraw |
        ControlStyles.UserPaint, true);
      BackColor = Color.Transparent;
   }
}

This code was devilishly simple! I used this panel as a parent control to my CustomRTB control in the windows form. Also, I could control the transparency of the panel by using:

CustomPanel.BackColor = Color.FromArgb(50, 0, 0, 0)

Just by sending the proper arguments in the above code, I could set the transparency and hue of the panel.

The Result

This method solved the editing and scrolling problems of the CustomRTB control and made me a happy man. Further testing of the control revealed no performance issues in the form. Later on that day, I created a single control from the two afore-mentioned ones which made it quite easy to manage them in a rich GUI. I had finally achieved what I had set out to do. I had successfully reduced hundreds of lines of code to less than twenty AND created a much superior control. That feeling you get when everything works as expected was literally choking me! This goes a long way in underlining the fact that huge chunks of code are not required in solving a problem, big or small. All it requires is good coding skills and a beautiful saturday morning!

P.S: A few months later, I found this question on Stack Overflow which did not have a suitable answer. Some people went to the extent of saying it was not possible to have transparent controls in windows forms. Hopefully, this post (and my answer to the question) would go someway in making people realise that with a powerful language like C#, a comprehensive framework like .NET and a simply outstanding IDE like Visual Studio 2012, impossible is nothing!

Advertisements

2 Comments Add yours

  1. Jeff says:

    I am getting the jumbled mess from the transparent richTextBox. This part works.

    However, the panel is not truly transparent. It seems it only is adopting the background color of the control behind it. In other words, I can’t see other controls, such as labels, behind the transparent panel.

    Were you able to achieve true transparency?

  2. Apologies for the late reply Jeff.

    You can try adding your background controls to the transparent panel instead. This will most certainly provide the true transparency you are looking for. I haven’t tried it yet so I do not know if this would impact the performance of the overall windows form. I am also unsure of any glitches that might crop up.

    Give it a shot and let me know if it works.

    Cheers 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s