0

I want to select some structures (polygons and rectangles) in a panel. I have used the new ExtendedPanel Class, for the opacity of the mouse panel.
panel1 is for the structure, extendedPanel1 is for the selected area of the mouse. (SetSelectionRect() ist the set of the selections area)

In the figure below, the red is the graph I drew on panel1, and the green is the rectangle selected by the mouse. In fact, it should present a green rectangle, which is the rectangle when the mouse selection ends, but now there are many. This shows that the transparency setting in the extendetPanel1 works after extendedPanel1.Invalidate();, but the historical rectangle drawn does not disappear.

Can you please tell me, how should I write the code for the mouse selection in the Panel?

I actually want to realize some polygons and editing. I drew some polygons (rectangles) in panel1, and now I want to use the mouse to select some parts and make some changes (such as deleting some polygons).
My thoughts on this are: Draw the polygons on panel1, and panel2 displays the selection by the mouse, but the bottom of panel2 is transparent.

Then, according to the coordinate calculation, etc., it is judged whether the geometric figure in panel1 is in the area selected in panel2. If it is, then I will delete it. I don’t know if my thoughts are reasonable. If you can provide a suitable solution, I am very grateful.

Sample image

code of extendetpanel:

public class ExtendedPanel : Panel
{
    private const int WS_EX_TRANSPARENT = 0x20;
    public ExtendedPanel()
    {
        SetStyle(ControlStyles.Opaque, true);
    }

    private int opacity = 0;
    [DefaultValue(0)]
    public int Opacity
    {
        get
        {
            return this.opacity;
        }
        set
        {
            if (value < 0 || value > 100)
                throw new ArgumentException("value must be between 0 and 100");
            this.opacity = value;
        }
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
            return cp;
        }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        using (var brush = new SolidBrush(Color.FromArgb(this.opacity * 255 / 100, this.BackColor)))
        {
            e.Graphics.FillRectangle(brush, this.ClientRectangle);
        }
        base.OnPaint(e);
    }
}

Code of paint and events:

        private void extendedPanel1_Paint(object sender, PaintEventArgs e)
    {

        base.OnPaint(e);           

        extendedPanel1.Opacity = 0;
        if (mouseDown)
        {
            using (Pen pen = new Pen(Color.Green, 1F))
            {
                pen.DashStyle = DashStyle.Dash;
                e.Graphics.DrawRectangle(pen, selection);
            }
        }
        
    }

    private void extendedPanel1_MouseDown(object sender, MouseEventArgs e)
    {
        selectionStart = extendedPanel1.PointToClient(MousePosition);
        mouseDown = true;
    }

    private void extendedPanel1_MouseUp(object sender, MouseEventArgs e)
    {
        mouseDown = false;
        SetSelectionRect();
        extendedPanel1.Invalidate();
    }

    private void extendedPanel1_MouseMove(object sender, MouseEventArgs e)
    {
        if (!mouseDown)
            return;
        selectionEnd = extendedPanel1.PointToClient(MousePosition);
        SetSelectionRect();
        extendedPanel1.Invalidate();
    }
KAYSAR
  • 1
  • 2
  • Hello and welcome to SO! `Can you please tell me, how should I write the code for the mouse selection in the panel?`, what specific issue are you having? – Trevor Aug 31 '20 at 12:03
  • Did you register the events using '+='? – jdweng Aug 31 '20 at 12:08
  • You really should avoid calling `base.OnPaint(e);` in an event handler, that call belongs to the `OnPaint()` override. You should invalidate the Control if you change the opacity level. It's not clear what `SetSelectionRect()` is doing (just sets `selection`?) Ext: you don't need `PointToClient(MousePosition)`, `MouseEventArgs` already gives you the location. `mouseDown` is also not needed, you should check whether the left mouse button is down. You should probably use a PictureBox instead of a Panel for this (long to explain). More... – Jimi Aug 31 '20 at 12:10
  • Not sure what you want. A non-persistent [rubberband](https://stackoverflow.com/questions/25348678/how-do-i-make-that-the-rectangle-first-location-will-be-the-mouse-cursor-locatio/25349796#25349796) rectangle? – TaW Aug 31 '20 at 12:29
  • Due to the word limit, I directly described it in the answer area. – KAYSAR Sep 01 '20 at 12:48
  • '+=': I did not use this for the events. Should I use this one? – KAYSAR Sep 01 '20 at 12:54
  • @Jimi In a transparent panel, can the panel be fully initialized by invalid controls? Now even if I initialize it now, the rectangle drawn before is still there. SetselectionsRect() is the area selected by the mouse. Could you please give me a better suggestion? – KAYSAR Sep 01 '20 at 12:57
  • [How to determine when Rectangles overlap or intersect?](https://stackoverflow.com/a/62948409/7444103). Combine with: [How to use the Paint event to draw shapes at mouse coordinates](https://stackoverflow.com/a/53708936/7444103) – Jimi Sep 01 '20 at 13:07
  • You can use [ControlPaint.DrawReversibleFrame](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.controlpaint.drawreversibleframe?view=netcore-3.1) to draw your "rubberband". If you draw the EXACT SAME rectangle over the previous one, then it is erased. – Idle_Mind Sep 01 '20 at 13:31
  • [Here's an example](https://stackoverflow.com/a/62903203/2330053) of what rubberbanding could look like. – Idle_Mind Sep 01 '20 at 13:38
  • @Jimi Actually, those are implemented on the form, I need to implement it on the geometric figures drawn by the panel, so the form method is not suitable – KAYSAR Sep 01 '20 at 13:53
  • All drawings work the same way, it doesn't matter much what is the surface. What is important is to handle a collection of shapes and use the appropriate methods (`Rectangle.Intersects()`/`IntersectsWith()`, `Rectangle.Contains(Point)` etc.) to determine when a shape intersects/is contained in another. After that, it's all quite simple (or it will be, after some testing :). If you want to draw rubber-bands, as Idle_Mind mentioned, you can also draw a rectangle without adding it to a collection of shapes, so next time you Invalidate the *canvas* it will *disappear*. – Jimi Sep 01 '20 at 16:35
  • @Jimi You are right, but the problem now is: The rubber-bands I want to draw is on a panel (panel1), so the ldle_Mind method is not suitable, because the method of drawing directly on the Form. – KAYSAR Sep 02 '20 at 11:13

0 Answers0