Reputation: 3637
Don't be frightened by the length of the post, it should be pretty straightforward. I'm just trying to be very speciffic, because lots of people have misunderstood me when I explained the problem before.
I looked around for a solution to this, but I didn't quite find what I'm looking for.
I'm trying to set the transparency settings on multiple nested controls that are dynamically added at runtime. I've tried using the program's overall Transparent Color, but that seems to draw the transparent layer AFTER it draws the control.
I want more control over what layers are transparent, so I can layer panels, PictureBox controls with non-rectangular-images, and some other things. I can't draw the Image in a Paint() event (which I have done to great success elsewhere) because these PictureBoxes have click, mouseover, context-menu, and other things associated with them.
So there's the limitations.
In the example below, the WinForm is supposed to mimic a book, with 'tabs' to jump to the next 'chapter' and various graphics displayed 'within the book.' Important technical bits below. Picture (slightly outdated)
FlowLayoutPanel FLP = A large rectangular panel. I want it 'completly transparent' because it is only used for its FlowLayout powers, and to move/resize lots of controls cleanly. It contains the following controls.
1) Panel LeftTabs = A panel containing the LeftTabs.
2) Panel Book = A panel containing lots of child controls. Has a background image (no transparency issues here, but the child controls are a problem).
3) Panel RightTabs = A panel containing the RightTabs.
***** Issue 1: Transparent tab panels ***** The tab panels contain overlapping PictureBox controls with rounded corners - kind of like filing folder tabs. The missing corners of these tabs are showing the background of the control underneath, rather than the image of the next-further-down tab. In the picture above, I was still using hand-arranged PictureBoxes, but now I'm moving the tabs into the tab panels and I want the background of those to be transparent.
***** Issue 2: Child Controls within the Book panel *****
The Book panel control contains numerous child panels (child layer 1), and each of those contains another PictureBox and a variable number of NumericUpDown controls (child layer 2).
The NUDs are fine, but the PictureBox (CL2) has more rounded corners.
The panels (CL1) should be completely transparent (only using them for grouping powers and logic), but that transparency should STOP at the Book panel level.
Hopefully that all made sense. I've tried numerous fixes in the past before giving up and kludging around the problem, but now I'm determined to do this right. I tried changing the shapes of the controls ([control].Region), but that solution is inconceivably messy and makes future changes (custom skins) nearly impossible.
Upvotes: 1
Views: 2225
Reputation: 3637
Short version:
I found a way around the problem.
It has to do with using the control's REGION.
By altering the Region of the control, I managed to fake a functional transparency system. It may not be the most efficient or user-friendly method, but it gets the job done.
int SizeW = this.Size.Width;
int SizeH = this.Size.Height;
int ArcSize = (int)((float)SizeW * 0.40 );
if (tabType == TabType.LeftTab)
{
//Make a six-sided polygon, a rectangle with the "outside" corners cut off.
//The next step will round the corners with Arcs
Point[] points = new Point[] {
new Point(SizeW, 0), new Point(ArcSize, 0),
new Point(0,ArcSize), new Point(0,SizeH-ArcSize),
new Point(ArcSize,SizeH), new Point(SizeW,SizeH)};
Byte[] bytes = new byte[] {
1, 1,
1, 1,
1, 1};
System.Drawing.Drawing2D.FillMode fm =
System.Drawing.Drawing2D.FillMode.Winding;
System.Drawing.Drawing2D.GraphicsPath tempGP =
new System.Drawing.Drawing2D.GraphicsPath(points, bytes, fm);
//add the arcs
ArcSize = ArcSize * 2;
tempGP.AddArc(0, 0, ArcSize, ArcSize, -90, -90);
tempGP.CloseFigure();
tempGP.AddArc(0, SizeH - ArcSize, ArcSize, ArcSize, 180, -90);
tempGP.CloseFigure();
Region tempRegion = new Region(tempGP);
this.Region = new Region(tempGP);
}
Upvotes: 2