Thursday, November 29, 2007

Five steps for creating a transparent user control

Guest post from Eyal Ron:

After much testing this is the correct formula for a truly transparent user control:

  1. Derive from Panel rather then UserControl.

  2. Override the OnPaintBackground function:
    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
    //do nothing
    }

  3. Override the OnMove function:
    protected override void OnMove(EventArgs e)
    {
    RecreateHandle();
    }

  4. Override the CreateParams property:
    protected override CreateParams CreateParams
    {
    get
    {
    CreateParams cp = base.CreateParams;
    cp.ExStyle = 0x00000020; //WS_EX_TRANSPARENT
    return cp;
    }
    }

  5. Override the OnPaint function:
    protected override void OnPaint(PaintEventArgs e)
    {
    Graphics g = e.Graphics;

    //Do your drawing here
    .
    .
    .

    g.Dispose();
    }

15 comments:

Anonymous said...

Awesome! This actually worked, unlike the dozen other solutions I found. Thanks!

Anonymous said...

You are most welcome.

Anonymous said...

You are most welcome.

Anonymous said...

I want to thank you as well. Thanks!!!

Jeff said...

Fantastic! Works with UserControl as well as a Panel. Thanks a ton!

Anonymous said...

Thanks a lot. I searched through all internet and most people don't know this trick. Good and easy.

Anonymous said...

Thank you very very much for excellent article. God bless you.

✞ Đ ä ɳ ї ệ Ŀ ✈ :: said...

how to implement this code? can anyone show me a sample of HOW-TO?
thanks

Anonymous said...

to avoid using RecreateHandle, and to reduce flicker, in the containing form or other such container, add the this:

(sorry only have a vb version offhand)



Protected Overrides ReadOnly Property CreateParams As System.Windows.Forms.CreateParams
Get
Return SetCompositeStyle(MyBase.CreateParams)
End Get
End Property


'-- place the following somewhere for reuse

Public Function
SetCompositeStyle(ByRef cp As System.Windows.Forms.CreateParams) As System.Windows.Forms.CreateParams
cp.ExStyle = cp.ExStyle Or ExtendedWindowStyles.WS_EX_COMPOSITED
Return cp
End Function


Public Enum ExtendedWindowStyles
WS_EX_COMPOSITED = &H2000000
WS_EX_APPWINDOW = &H40000
WS_EX_ACCEPTFILES = &H10
WS_EX_CLIENTEDGE = &H200
WS_EX_CONTEXTHELP = &H400
WS_EX_CONTROLPARENT = &H10000
WS_EX_DLGMODALFRAME = &H1
WS_EX_LAYERED = &H80000
WS_EX_LAYOUTRTL = &H400000
WS_EX_LEFTSCROLLBAR = &H4000
WS_EX_LEFT = &H0
WS_EX_LTRREADING = &H0
WS_EX_MDICHILD = &H40
WS_EX_NOACTIVATE = &H8000000
WS_EX_NOINHERITLAYOUT = &H100000
WS_EX_NOPARENTNOTIFY = &H4
WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE)
WS_EX_RIGHT = &H1000
WS_EX_RIGHTSCROLLBAR = &H0
WS_EX_RTLREADING = &H2000
WS_EX_STATICEDGE = &H20000
WS_EX_TOOLWINDOW = &H80
WS_EX_TOPMOST = &H8
WS_EX_TRANSPARENT = &H20
WS_EX_WINDOWEDGE = &H100
End Enum

Anonymous said...

hi

now i am trying to create the user control in transparent i seen your code but i am not able to understand
so pls can you send the sample project for understanding

Thanks & Regards
susi

Joaquim said...

and how do it for VB2010?
i have nice code, but is very slow:(
can anyone help please?

Anonymous said...

Can anyone explain how to make this work for a PictureBox?

Hakan said...

The original code works - brilliant!

Anonymous said...

Panel&Label WinForms control with transparent support

Josh said...

Reproduced the sample code and the result is my panel is drawn with my PNG that has a transparent background, but everywhere that should be transparent is just black.

The only thing that is different in my code is that I added code to the OnPaint method so that it draws the PNG I need it to draw:

protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.FromArgb(0, 0, 0, 0));

Bitmap bmp = new Bitmap(m_Image);
bmp.MakeTransparent();

g.DrawImage(bmp, 0, 0,100,100);
g.Dispose();
}