c#如何检测使用winforms时是否点击了一条线(绘制/绘制在窗体上)? [英] c# How do I detect if a line (painted/drawn on a form) has been clicked on when using winforms?

查看:148
本文介绍了c#如何检测使用winforms时是否点击了一条线(绘制/绘制在窗体上)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个winforms应用程序

这是我的代码

pre $ code >使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
使用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 =新的Point(100,0);
myline.P2 =新点(200,80);

gr.DrawLine(新笔(Color.Red),myline.P1,myline.P2);


矩形r =新矩形(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;组; }
}

我的问题是这样的。



我可以绘制一个矩形,并且我可以看到一个点是否在其中。



因此,我可以扩展程序以在点击窗体就在矩形内。 Rectangle有一个很好的包含功能。



但我想为Line做同样的事情。



问题是,winforms没有Line类。我可以编写自己的Line类,但问题仍然存在。如何查找点击是否落在它上面?



我注意到WPF有这样一个类如何识别鼠标点击一行?



但是我使用的是winforms。 使用 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); 被错误地修正为路径.AddLine(p1,p2); 现在答案可以正常工作。


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 can see whether a point is within it.

So I could extend the program to say "yes" when a click on the form is within the rectangle. The Rectangle has a Contains function which is great.

But I want to do the same for Line.

The problem, is that winforms has no Line class. I could write my own Line class, but the problem remains.. how to find whether a click landed on it?

I notice that WPF has such a class How do I recognize a mouse click on a line?

But i'm using winforms.

解决方案

Using GraphicsPath.IsOutlineVisible method you can determine whether the specified point is under the outline of the path when drawn with the specified Pen. You can set width of the pen.

So you can create a GraphicsPath and then add a line using GraphicsPath.AddLine to the path and check if the path contains the point.

Example:

The below method, checks if the p is on the line with end points p1 and p2 using the specified width.

You can use wider width to increase the tolerance or if the line is wider than 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;
}

Note added by barlop

The statement path.AddLine(p1,p1); in this answer was mistaken and was corrected to path.AddLine(p1,p2); Now the answer works and works well.

这篇关于c#如何检测使用winforms时是否点击了一条线(绘制/绘制在窗体上)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆