User Control with transparent background

20,348

Solution 1

This is in general a very fundamental restriction in Windows. A window overlaps another window and obstructs whatever is behind it. Everybody's favorite answer, use ControlStyles.SupportsTransparentBackColor, is no workaround, it is already turned on for UserControl so setting it again makes no difference.

The style flag simulates window transparency. It does so by altering the way the window paints itself. It first asks the Parent to draw itself inside the window to provide the background, then draws itself on top of it. So by setting the BackColor property to Color.Transparent, you can expect to see the Parent window's pixels as the background.

And you do. The Parent of your user control is the form. It dutifully draws itself first and that produces the gray edges on the left and the right. What you hoped for was to also see the pixels of the other user controls. But that doesn't work, it only asks the Parent to draw, not any other control that happens to be overlapped as well. That certainly isn't impossible, it is just ugly and slow. This KB article shows the approach. Rather emphasizing the "ugly" moniker.

Clearly you can improve your UserControl, there's on the face of it no point in having these transparent edges at the left and right of the Panel. So set the panel's Location property to (0, 0) and the Dock property to Fill. Now every user control is nothing but a "node" and you don't need nor want to see pieces of any overlapped other "node". Drawing any lines between the nodes is going to require implementing the Paint event of the form.

If you truly need this kind of transparency then you are going to have to do this differently. You have to give up on the idea of using a window for each node. One way to do so is to just paint them. If you do that in the right order then you'll have no problem simulating true transparency, created by layering paint and just not draw where you need to see the "background". It will also be a lot faster, controls are expensive. You however will to give up on the convenience of using controls, you'll have to write code instead. Things like mouse hit testing become more complicated. And the text box will certainly be a hangup if it isn't actually supposed to be a Label (surely it does?) Or use a GUI class library that has given up on using a window as a control. Like WPF. And don't forget that there are plenty of libraries that already do this for you, connected nodes are a very common user interface paradigm. Visio for example.

Solution 2

try this in the constructor of your UserControl:

this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;

Solution 3

You also can try this :

     public partial class UCTransparent : UserControl
     {

         public UCTransparent()
         {
                InitializeComponent(); 
         }
         protected override CreateParams CreateParams
         {
                get
                {
                       CreateParams cp = base.CreateParams;
                       cp.ExStyle |= 0x20;
                       return cp;
                }
         }

         protected override void OnPaintBackground(PaintEventArgs e)
         {
             base.OnPaintBackground(e);
         }
      }
Share:
20,348
Ace
Author by

Ace

Updated on July 09, 2022

Comments

  • Ace
    Ace almost 2 years

    I've a simple user control that actually is just a panel, when I click in that panel, there will be a child user control added. that child is just another user control where I set width = 150px & height = 100px and the background color to transparent. also it has a textbox in the center that is 100 x 100 px.

    this base structure will be a Node Based Interface in the future, where each box will have connection anchors and logic btn's or something like that in it.

    my problem is that if i click a few times in the panel and the added box overlapy another, the transparency wont take effect.

    here's a screenshot

    enter image description here

    how can i fix that issue ? is there a allowTransparency or something like that ?

    there is also an issue with the order of the drawing, the new added blocks are always behind the other one's.

    if you wish to see the code for this, let me know , but i don't think that there is anything relevant for this.

    also, if you know a better way to implement a node graph, please feel free to tell me.

    EDIT

    following code was the first thing I've tried before I've even thought of posting a question in StackOverFlow.

    SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    MakeTransparentControls(this);
    

    so please don't take this as a duplicate question or posting that code as answer

  • Ace
    Ace over 11 years
    it already IS in my code.. that way the first what google was showing me as i've searched the problem in the web befor posting it here ^^
  • Ace
    Ace over 11 years
    well first of all , thank for this huge text. i tryed it befor usinf WPF and GDI+, but it was too confusing to me. then i was thinking about using openGL or D3D but i thought this would be too much for the porpose. do you have any example or reference for me usinf WPF or any lib's ?
  • Ace
    Ace over 11 years
    i also thought of using libarys that do what i need, but the task is to make my own Node Graph. so using a libary would be my last choice , but i could look ar the source and lern some stuff i think.
  • Ace
    Ace over 11 years
    this was the first thing google was giving me when i was searching for this problem befor i've postet the question. so it doesn't work in my case.
  • Brandon
    Brandon almost 10 years
    This actually sort of worked, but it did some crazy stuff to my control at run time.