I know this question had been asked more than a few times, but so far I haven't been able to find a good solution for it.
I've got a panel with other control on it.
I want to draw a line on it and on top of all the controls in the panel
I came across 3 types of solutions (non of them worked the way I wanted) :
Get the desktop DC and Draw on the screen.
This will draw on other applications if they overlap the form.
Overriding the panel's "CreateParams":
=
protected override CreateParams CreateParams { get { CreateParams cp; cp = base.CreateParams; cp.Style &= ~0x04000000; //WS_CLIPSIBLINGS cp.Style &= ~0x02000000; //WS_CLIPCHILDREN return cp; } }
//NOTE I've also tried disabling WS_CLIPSIBLINGS
and then drawing the line OnPaint(). But... Since the panel's OnPaint is called before the OnPaint of the controls in it, the drawing of the controls inside simply paints on top of the line.
I've seen someone suggest using a message filter to listen to WM_PAINT mesages, and use a timer, but I don't think this solution is either "good practice" or effective.
What would you do ? Decide that the controls inside have finished drawing after X ms, and set the timer to X ms ?
This screen shot shows the panel with WS_CLIPSIBLINGS and WS_CLIPCHILDREN turned off.
The Blue line is painted at the Panel's OnPaint, and simply being painted on by the textboxes and label.
The Red line is painted on top only because it's not being painted from the panel's OnPaint (It's actually painted as a result of a Button being clicked)
3rd: Creating a transparent layer and drawing on top of that layer.
I've created a transparent control using:
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT return cp; } }
The problem is still, putting the transparent control on top of the Panel and all its controls.
I've tried bringing it to the front using: "BringToFront()" , but it didn't seem to help.
I've put it in the Line control's OnPaint() handler.
Should I try putting it somewhere else ??
- This also creates issue with having another control on top of the panel. (catching the mouse clicks etc..)
Any help would be greatly appreciated!
**EDIT: The black line is a sample of what I was trying to do. (used windows paint to paint it)
To create a group of controlsDrag a Panel control from the Windows Forms tab of the Toolbox onto a form. Add other controls to the panel, drawing each inside the panel.
Panel creates a group of Controls. This Control provides a simple frame for putting sub-controls inside. These sub-Controls include Buttons and Textboxes. It furthur provides an optional border and ways to change its visibility.
In order to draw shapes in C# a start point and end point coordinates, and a Pen control must be defined first. The value of x is the location of the point along the x-axis, the 0 is at the extreme left. The value of y is the location of the point along the y-axis, the 0 is at the extreme top.
Turns out this is a whole lot easier than I thought. Thanks for not accepting any of my other answers. Here is the two-step process for creating a Fline (floating line - sorry, it's late):
Step 1: Add a UserControl to your project and name it "Fline". Add the following to the using statements:
using System.Drawing.Drawing2D;
Step 2: Add the following to the Fline's Resize event:
int wfactor = 4; // half the line width, kinda // create 6 points for path Point[] pts = { new Point(0, 0), new Point(wfactor, 0), new Point(Width, Height - wfactor), new Point(Width, Height) , new Point(Width - wfactor, Height), new Point(0, wfactor) }; // magic numbers! byte[] types = { 0, // start point 1, // line 1, // line 1, // line 1, // line 1 }; // line GraphicsPath path = new GraphicsPath(pts, types); this.Region = new Region(path);
Compile, and then drag a Fline onto your form or panel. Important: the default BackColor is the same as the form, so change the Fline's BackColor to Red or something obvious (in the designer). One weird quirk about this is that when you drag it around in the designer it shows as a solid block until you release it - not a huge deal.
This control can appear in front of or behind any other control. If you set Enabled to false, it will still be visible but will not interfere with mouse events on the controls underneath.
You'll want to enhance this for your purposes, of course, but this shows the basic principle. You can use the same technique for creating a control of whatever shape you like (my initial test of this made a triangle).
Update: this makes a nice dense one-liner, too. Just put this in your UserControl's Resize event:
this.Region=new Region(new System.Drawing.Drawing2D.GraphicsPath(new Point[]{new Point(0,0),new Point(4,0),new Point(Width,Height-4),new Point(Width,Height),new Point(Width-4,Height),new Point(0,4)},new byte[]{0,1,1,1,1,1}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With