Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User Control with transparent background

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

like image 584
Ace Avatar asked Jan 20 '13 12:01

Ace


3 Answers

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.

like image 186
Hans Passant Avatar answered Nov 09 '22 05:11

Hans Passant


try this in the constructor of your UserControl:

this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;
like image 8
Aniket Inge Avatar answered Nov 09 '22 05:11

Aniket Inge


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);
         }
      }
like image 2
MFUser Avatar answered Nov 09 '22 04:11

MFUser