Creating a .NET Transparent Panel

Creating a .NET Transparent Panel

June 2, 2018

In the overabundance of .NET controls, one can probably forgive Microsoft for not having enough Properties for certain controls. On the other hand, some Properties are quite redundant, but that is just my opinion. I have always wanted an Opacity property for most .NET controls. It is probably an impractical thought, but it would have saved me a ton of hours manipulating and improving existing .NET controls.

 

Yes, you are able to set the Background color of controls to Transparent, but this causes the control to be completely see-through. What if you wanted the control to only be semi-transparent, or what if you wanted to be able to set the control's opacity?

I'm sure I'm not alone on this.

 

To make controls semi-transparent, you would need to create a component that inherits from the desired control. This will cause the newly created component to act and look like the control in question. Then, you would have to override the existing control's properties and methods.

 

In your project today, you will create a new Panel component, as stated above, add a new property named Opacity to the panel, override its Paint event to compensate for the new opacity settings, and add the semi-transparent parameter to the Panel window object. You can follow along in either C# or VB.NET.

 

Practical

 

Create a new Windows Forms project in either C# or VB.NET. Name it anything descriptive. Once the project has been created, add a Component to your project by selecting Project, Add Component. Figure 1 shows a dialog that will be displayed. Provide a nice name for your component.

 

 

 

 

C#
 
using System.ComponentModel;
 
 

public class ExtendedPanel : Panel
{
    private const int WS_EX_TRANSPARENT = 0x20;
    public ExtendedPanel()
    {
        SetStyle(ControlStyles.Opaque, true);
    }

    private int opacity = 50;
    [DefaultValue(50)]
    public int OpacitySet
    {
        get
        {
            return this.opacity;
        }
        set
        {
            if (value < 0 || value > 100)
                throw new ArgumentException("value must be between 0 and 100");
            this.opacity = value;
        }
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
            return cp;
        }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        using (var brush = new SolidBrush(Color.FromArgb(this.opacity * 255 / 100, this.BackColor)))
        {
            e.Graphics.FillRectangle(brush, this.ClientRectangle);
        }
        base.OnPaint(e);
    }
}

 
VB.NET
 
Imports System.ComponentModel
 

Public Class ExtendedPanel
    Inherits Panel

    Private Const WS_EX_TRANSPARENT As Integer = &H20

    Public Sub New()
        SetStyle(ControlStyles.Opaque, True)
    End Sub

    Private opacity As Integer = 50

    <DefaultValue(50)>
    Public Property OpacitySet As Integer
        Get
            Return Me.opacity
        End Get
        Set(ByVal value As Integer)
            If value < 0 OrElse value > 100 Then Throw New ArgumentException("value must be between 0 and 100")
            Me.opacity = value
        End Set
    End Property

    Protected Overrides ReadOnly Property CreateParams As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
            Return cp
        End Get
    End Property

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Using brush = New SolidBrush(Color.FromArgb(Me.opacity * 255 / 100, Me.BackColor))
            e.Graphics.FillRectangle(brush, Me.ClientRectangle)
        End Using

        MyBase.OnPaint(e)
    End Sub
End Class