C # How to determine if a button was pressed (drawn / drawn on a form) when using winforms?

I have a winforms application

Here is my code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication12
{
    public partial class Form1 : Form
    {
        Graphics gr;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            gr = this.CreateGraphics();

            MyLine myline = new MyLine();
            myline.P1 = new Point(100, 0);
            myline.P2 = new Point(200, 80);

            gr.DrawLine(new Pen(Color.Red), myline.P1,myline.P2);


            Rectangle r = new Rectangle(0, 0, 50, 50);


            gr.DrawRectangle(new Pen(Color.Teal, 5), r);

            if (r.Contains(0,25)) MessageBox.Show("within");

        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            gr.Clear(this.BackColor);
        }


    }
}

class MyLine
{    
    public Point P1 {get; set;}
    public Point P2 { get; set; }
}

My problem is this.

I can draw a rectangle and I see if there is a dot in it.

So I could expand the program to say yes when the click on the shape is inside the rectangle. The rectangle has a Contain function, which is great.

But I want to do the same for Line.

The problem is that winforms does not have a Line class. I could write my own Line class, but the problem remains. How to find if clicked on it?

I noticed that WPF has such a class. How to recognize a mouse click on a line?

But I use winforms.

+2
2

GraphicsPath.IsOutlineVisible, , Pen. .

, GraphicsPath, , GraphicsPath.AddLine , .

:

, p p1 p2 .

1:

bool IsOnLine(Point p1, Point p2, Point p, int width = 1)
{
    var isOnLine= false;
    using (var path = new GraphicsPath())
    {
        using (var pen = new Pen(Brushes.Black, width))
        {
            path.AddLine(p1,p2);
            isOnLine = path.IsOutlineVisible(p, pen);
        }
    }
    return isOnLine;
}

barlop

path.AddLine(p1,p1); path.AddLine(p1,p2); .

+3

Line, , .
Form_Click

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication
{
    public partial class Form1 : Form
    {
        Line myLine;
        int x1 = 10;
        int x2 = 40;
        int y1 = 0;
        int y2 = 30;
        public Form1()
        {
            InitializeComponent();
            myLine = new Line() { Start = new Point(x1, y1), Stop = new Point(x2, y2), Epsilon = 10 };
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.FromArgb(255, 0, 0, 0));
            e.Graphics.DrawLine(pen, x1, y1, x2, y2);
            pen.Dispose();
        }

        private void Form1_Click(object sender, EventArgs e)
        {
            MouseEventArgs me = (MouseEventArgs)e;
            bool contain = myLine.contain(new Point(me.X,me.Y));
        }
    }

    public class Line
    {
        public Point Start { get; set; }
        public Point Stop { get; set; }
        public float Epsilon { get; set; }

        public bool contain(Point p)
        {
            // y = mx + c
            float m = (Stop.Y - Start.Y) / (Stop.X - Start.X);
            float c = Stop.Y - (m * Stop.X);
            return p.X >= Math.Min(Start.X, Stop.X)
                && p.X <= Math.Max(Start.X, Stop.X)
                && p.Y >= Math.Min(Start.Y, Stop.Y)
                && p.Y <= Math.Max(Start.Y, Stop.Y)
                && Math.Abs(Math.Abs(p.Y) - Math.Abs((m * p.X) + c)) < epsilon; //with relax rules
                //&& (p.Y == (m*p.X)+c); // strict version
        }
    }

UPDATE
, X1 == X2. .

+1

All Articles