C# 绘制可点击的线条和形状

C# 绘制可点击的线条和形状,c#,winforms,C#,Winforms,我有一个txt文件中的行列表,C程序需要从txt文件中收集数据,并从txt文件中绘制每一行。我需要使它们以某种方式可点击,因此,如果我点击一行,程序会识别出该行是什么特定的行对象,我可以选择删除该行并在没有该行的情况下重新绘制图像(并重复此操作,直到我只获得所需的行) 我只是不知道我如何才能做到这一点,我应该使用什么技术为可点击的绘图部分 我尝试使用winform,因为它似乎适合画布和显示、绘制功能等方面的工作。。我用一个小的层次结构系统创建了一些类来存储txt中的数据。在上面有一个图像类,它有

我有一个txt文件中的行列表,C程序需要从txt文件中收集数据,并从txt文件中绘制每一行。我需要使它们以某种方式可点击,因此,如果我点击一行,程序会识别出该行是什么特定的行对象,我可以选择删除该行并在没有该行的情况下重新绘制图像(并重复此操作,直到我只获得所需的行)

我只是不知道我如何才能做到这一点,我应该使用什么技术为可点击的绘图部分

我尝试使用winform,因为它似乎适合画布和显示、绘制功能等方面的工作。。我用一个小的层次结构系统创建了一些类来存储txt中的数据。在上面有一个图像类,它有一个形状列表(程序只处理一个图像,但是图像可以包含更多的形状,一些在另一个图像中),形状类有一个线条列表,线条类有int变量:fromX,fromY,toX,toY 我能够从txt中获取所有数据并加载到程序中,我将一些数据写入控制台,它们正确存储,我可以从图像对象中获取每一行的坐标。现在我需要一个接一个地画出每一个线条对象,并使它们可点击(可能是一个onclick事件,返回或存储点击线条的数据),但我陷入困境的部分是,我不知道如何计算点击是否在线条上,如果在线条上,那么哪个线条对象才是返回正确数据的对象

/*
Example of input file (two triangle and one pentagon on the pic, lines with ? are shape dividers)

X:Y>X:Y
810:-448>935:-532
935:-532>806:-534
806:-534>804:-449
?:?>?:?
597:-529>673:-411
673:-411>747:-531
747:-531>597:-529
?:?>?:?
475:-275>582:-355
582:-355>541:-487
541:-487>411:-487
411:-487>370:-355
370:-355>475:-275
?:?>?:?
*/

//As I mentioned I stored the data in line objects
class Line
    {
        public int startX;
        public int startY;
        public int endX;
        public int endY;

        public Line(int startX, int startY, int endX, int endY)
        {
            this.startX = startX;
            this.startY = startY;
            this.endX = endX;
            this.endY = endY;
        }

    }

//Every shape is an object with a list of the Line objects
 class Shape
    {
        public List<Line> lines = new List<Line>();

        public void AddLine(Line a)
        {
            this.lines.Add(a);
        }

        public void RemoveLine(Line a)
        {
            this.lines.Remove(a);
        }

        public void ResetShape()
        {
            this.lines.Clear();
        }

        public Line GetLine(int index)
        {
            return this.lines[index];
        }
    }

//Image class looks similar, it has a List of Shapes, the main difference is the constructor.
//The constructor get the file path as parameter, opens it, read and store data
//Split every line, get the coordinates, make line objects and add them to a temp Shape object's list
//When the read reach a divider it adds the temp Shape object to the Image's shape list
//Then reset the temp Shape object and continue to collect new lines untile the file reach the last line (which is a divider) 
/*
输入文件示例(图片上的两个三角形和一个五角大楼,带?的线是形状分隔符)
X:Y>X:Y
810:-448>935:-532
935:-532>806:-534
806:-534>804:-449
?:?>?:?
597:-529>673:-411
673:-411>747:-531
747:-531>597:-529
?:?>?:?
475:-275>582:-355
582:-355>541:-487
541:-487>411:-487
411:-487>370:-355
370:-355>475:-275
?:?>?:?
*/
//正如我提到的,我将数据存储在line对象中
班级线
{
公共int startX;
公共国际标准;
公共int endX;
公共内部;
公共线路(int startX、int startY、int endX、int endY)
{
this.startX=startX;
this.startY=startY;
this.endX=endX;
this.endY=endY;
}
}
//每个形状都是一个具有线对象列表的对象
阶级形态
{
公共列表行=新列表();
公共无效添加行(a行)
{
本.行.加入(a);
}
公共空间移除线(a行)
{
本.行.删除(a);
}
公共形状()
{
这个.lines.Clear();
}
公共行GetLine(int索引)
{
返回此。行[索引];
}
}
//Image类看起来很相似,它有一个形状列表,主要区别在于构造函数。
//构造函数获取文件路径作为参数,打开它,读取并存储数据
//分割每条线,获取坐标,创建线对象并将它们添加到临时形状对象的列表中
//当读取到达分隔符时,它会将临时形状对象添加到图像的形状列表中
//然后重置临时形状对象并继续收集新行,直到文件到达最后一行(这是分隔符)

尝试使用继承。类型控件(System.Windows.Forms.Control)具有
单击方法(以及一些其他鼠标和键盘事件)

然后,如果要向其添加单击事件,只需使用:

private void SomeMethod()
{
    Shape shape = new Shape();
    shape.Click += Shape_Click;
}

private void Shape_Click(object sender, System.EventArgs e)
{
    // Do Something
}
如果要将其缩短,可以使用以下选项:

Shape shape = new Shape();
shape.Click += (object sender, System.EventArgs e) =>
{
    // Do Something
};
它做同样的事情


祝你好运

尝试使用继承。类型控件(System.Windows.Forms.Control)具有
单击方法(以及一些其他鼠标和键盘事件)

然后,如果要向其添加单击事件,只需使用:

private void SomeMethod()
{
    Shape shape = new Shape();
    shape.Click += Shape_Click;
}

private void Shape_Click(object sender, System.EventArgs e)
{
    // Do Something
}
如果要将其缩短,可以使用以下选项:

Shape shape = new Shape();
shape.Click += (object sender, System.EventArgs e) =>
{
    // Do Something
};
它做同样的事情


祝你好运

基本上,您应该参考GDI+进行渲染,并扩展
Shape
Line
类来实现接收鼠标点击坐标和进行点击测试的函数,这样您将有一个全新的winform领域需要探索。这里有很多示例,例如或。谢谢,您提供的Reza Aghaei链接非常有用,非常感谢你们!我想我现在就可以完成这个任务了:)基本上,你应该参考GDI+来进行渲染,并扩展你的
Shape
Line
类来实现接收鼠标点击坐标和进行点击测试的函数,你将有一个全新的winform领域需要探索,例如,或者。谢谢你,你提供的Reza Aghaei链接真的很有用,非常感谢你们!我想我现在就能完成这个任务了:)