Click here to Skip to main content
Click here to Skip to main content

Making Transparent Controls - No Flickering

By , 16 Aug 2012
 

Introduction   

When I wrote the article "Making Transparent Control" in 2005, the feature that I knew back then to get transparency was using the CreateParams class. Unfortunately this solution is not perfect and did the control get flickering. This let me sad.

Later, I tried to work on a new solution that could eliminate all the issues presented with the version made with CreateParams. The basic idea was to capture the image behind of the Control and use it as background. Finally, after exploring thoroughly the MSDN library I came across the DrawToBitmap method and finally arrived at the solution that I so wanted.

Since then, I've been using this new control and now would like to share that solution with the CodeProject community. The TranspControl and the DemoProgram were created under Windows 7 X64 platform and no problems were noted during the tests.

The following will describe the most important features of TranspControl:

Transparency Modes

The background of TranspControl is designed to have two modes of transparency. This will allow the control to be used in the most diverse application situations. In both modes, the non-background part can be semi-transparent, opaque or even transparent.

Glass Mode

In Glass mode, the background is like a glass. It can be translucent, semi-transparent or opaque. The level of transparency must be adjusted in the Opacity property. The Opacity property ranges from 0 to 100 where the value 0 makes the Control translucent and the value 100 makes the Control fully opaque. The Opacity affects also the fill color of drawn objects, such as shapes, for example. The fill color is determined in the FillColor property and the background color is determined in the GlassColor property. Setting the GlassColor property to color Transparent you get a translucent background.

True Transparent Background

In this mode, the Control region does not contain a background and only the drawn object is rendered. There, you can also set the level of transparency through the Opacity property.

In the figure shown above, the color of the shape border line was set to transparent color.

Setting the FillColor property to color Transparent, the inner part of the shape will not be rendered and you get an effect like a holed shape.  

Semitransparent Image

Additionally, TranspControl has support for semitransparent image. The effect of the image transparency is also adjusted in the Opacity property. A transparency key is provided in order you can determine the transparent color for the image background.

The picture shown above has a white color background. So, the key color was set to the color white. As you can see, the background of the image became transparent.

Getting the Background

The trick to get an effect of transparent background is to grab the image behind the Control to the Control itself. The method DrawToBitmap is very appropriate for this purpose.

For reasons of discipline, this is done in the OnPaintBackgroud method. See the code.

protected override void
OnPaintBackground(PaintEventArgs e)
{
    base.OnPaintBackground(e);
    Graphics g = e.Graphics;
 
    if (Parent != null && !drag)
    {                    
        int index = Parent.Controls.GetChildIndex(this);
 
        for (int i = Parent.Controls.Count - 1; i > index; i--)
        {
            Control c = Parent.Controls[i];
            if (c.Bounds.IntersectsWith(Bounds) && c.Visible)
            {
                Bitmap bmp = new Bitmap(c.Width,
                c.Height, g);
                c.DrawToBitmap(bmp, c.ClientRectangle);
                g.TranslateTransform(c.Left - Left, c.Top - Top);
                g.DrawImageUnscaled(bmp, Point.Empty);
                g.TranslateTransform(Left - c.Left, Top - c.Top);
                bmp.Dispose();
            }
        }
    }
 
    if (BackImage != null && GlassMode && !drag)
    {
        Bitmap image = new Bitmap(BackImage);
            image.MakeTransparent(TranspKey);
            float a = (float)opacity / 100.0f;
 
        float[][] mtxItens = {
        new float[] 
            {1,0,0,0,0},
        new float[]
            {0,1,0,0,0},
        new float[]
            {0,0,1,0,0},
        new float[]
            {0,0,0,a,0},
        new float[]
            {0,0,0,0,1}};
        ColorMatrix colorMatrix = new ColorMatrix(mtxItens);
 
        ImageAttributes imgAtb = new ImageAttributes();
       
imgAtb.SetColorMatrix(
        colorMatrix,
        ColorMatrixFlag.Default,
        ColorAdjustType.Bitmap);
 
        g.DrawImage(
                image,
               
ClientRectangle,
                0.0f,
                0.0f,
                image.Width,
                image.Height,
                GraphicsUnit.Pixel,
                imgAtb);
    }
}

Drawing the Control

Here you draw your code. Just for a sample I drew a simple ellipse. See the code.

protected override void
OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
     
    ///////////////////////////////
    // SETTINGS          //
    ///////////////////////////////
 
    Graphics g = e.Graphics;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
   
    g.CompositingQuality = CompositingQuality.GammaCorrected;
 
    RectangleF bounds = this.ClientRectangle;
    alpha = (opacity * 255) / 100;
         
    float penWidth = (float)LineWidth;
    Pen pen = new Pen(Color.FromArgb(alpha, ForeColor), penWidth);
    pen.Alignment = PenAlignment.Center;
 
    Brush brushColor = new SolidBrush(Color.FromArgb(alpha,
        FillColor));
    Brush bckColor = new SolidBrush(Color.FromArgb(alpha,
        GlassColor));
 
    ///////////////////////////////
    //    DRAW YOUR SHAPE HERE   //
    ///////////////////////////////
 
    GraphicsPath shape = new GraphicsPath();
    GraphicsPath regionShape = new GraphicsPath();
    GraphicsPath innerShape = new GraphicsPath();
            
    // Create a shape region for non glass mode
   
    regionShape.AddEllipse(bounds);
    Region region = new Region(regionShape);
 
    // Create the inner region for non glass mode
    RectangleF inner = bounds;
   
    inner.Inflate(-penWidth, -penWidth);
   
    inner.Inflate(-2.0f, -2.0f);
   
    innerShape.AddEllipse(inner);
    Region innerRegion = new Region(innerShape);
         
    // Fill the region background
    if (GlassMode)
    {
        Region = new Region();
        if (GlassColor != Color.Transparent && Opacity > 0)
        {
            g.FillRegion(bckColor, Region);
        }
    }
    else
    {             
        // Make a hole inside the shape if FillColor is transparent
        if (FillColor == Color.Transparent || Opacity == 0)
        {
            region.Exclude(innerRegion);      

        }
        Region = region;
    }
    // Add a shape to the path
   
    bounds.Inflate(-1.0f, -1.0f); //fit the
    ellipse inside the region
   
    shape.AddEllipse(bounds);
 
    // Fill the shape with a color
    if (FillColor != Color.Transparent && Opacity > 0)
    {
        g.FillPath(brushColor, shape);
    }
 
    // Draw the shape outline
    bounds.Inflate(-penWidth / 2.0f, -penWidth / 2.0f);
    if (ForeColor != Color.Transparent && Opacity > 0)
    {
        g.DrawEllipse(pen, bounds);
    }
 
    ///////////////////////////////
    //       FREES MEMORY        //
    ///////////////////////////////
 
    brushColor.Dispose();
    bckColor.Dispose();
    pen.Dispose();
    regionShape.Dispose();
    innerShape.Dispose();
    shape.Dispose();
   
    innerRegion.Dispose();
    region.Dispose();
    }

}

Examples

Below you can see some examples I have used to test the TranspControl component. The following Form properties were changed:

BackColor:         Color.White
BackgroundImage:   TechPaper.png
DoubleBuffered:    True

On the right side of the Form there are picture boxes behind the TranspControl. The picture boxes contain animated gif images and you can watch the animation even they are behind the Control.

As another point of interest is the circle over the button. There you can press the button with the mouse even in the inner part of the circle.

Cheers. Hope this article can be helpful.

License

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

About the Author

Nildo Soares de Araujo
CEO Digital Automation Ltda
Brazil Brazil
Member
Nildo Soares de Araujo
C# enthusiast. Control Systems engineer with expertise in industrial automation. Developed a complete library of Control Systems components such as PID, Integral Control, n-order Filters and many others functions written in SCL language.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
BugGlitch when moving near other transp controls Pinmemberseljo5 Apr '13 - 6:09 
GeneralRe: Glitch when moving near other transp controls Pinmemberseljo.myeri5 Apr '13 - 12:14 
GeneralRe: Glitch when moving near other transp controls PinmemberNildo Soares de Araujo6 Apr '13 - 7:20 
QuestionNeed help for using it PinmemberSirko König18 Mar '13 - 22:07 
AnswerRe: Need help for using it PinmemberNildo Soares de Araujo19 Mar '13 - 9:30 
GeneralMy vote of 5 Pinmemberaalhanane25 Feb '13 - 1:56 
GeneralRe: My vote of 5 PinmemberNildo Soares de Araujo26 Feb '13 - 2:55 
GeneralMy vote of 5 PinmemberA.J.Bauer13 Feb '13 - 21:03 
GeneralRe: My vote of 5 PinmemberNildo Soares de Araujo14 Feb '13 - 4:26 
GeneralMy vote of 5 PinmemberPavelmoje8 Feb '13 - 11:12 
GeneralRe: My vote of 5 PinmemberNildo Soares de Araujo14 Feb '13 - 4:26 
GeneralMy vote of 5 Pinmemberdoanhathanh7 Dec '12 - 3:34 
GeneralRe: My vote of 5 PinmemberNildo Soares de Araujo7 Dec '12 - 5:24 
QuestionOptimizations [modified] Pinmemberjellev26 Nov '12 - 12:05 
AnswerRe: Optimizations PinmemberNildo Soares de Araujo26 Nov '12 - 13:46 
QuestionRe: Optimizations Pinmemberseljo5 Apr '13 - 6:48 
QuestionRe: Optimizations Pinmemberseljo5 Apr '13 - 12:00 
GeneralMy vote of 1 Pinmemberaalhanane9 Nov '12 - 9:27 
GeneralRe: My vote of 1 PinmemberNildo Soares de Araujo9 Nov '12 - 9:41 
GeneralRe: My vote of 1 Pinmemberaalhanane25 Feb '13 - 1:54 
GeneralMy vote of 5 Pinmemberbalejandro26 Oct '12 - 8:13 
GeneralRe: My vote of 5 PinmemberNildo Soares de Araujo26 Oct '12 - 16:11 
QuestionCan this be applied to other controls? [modified] PinmemberBoiledham10 Oct '12 - 10:41 
AnswerRe: Can this be applied to other controls? PinmemberNildo Soares de Araujo22 Oct '12 - 3:09 
GeneralMy vote of 5 PinmemberCesar Sampaio6 Oct '12 - 14:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 16 Aug 2012
Article Copyright 2008 by Nildo Soares de Araujo
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid