C#在(位图图像​​)点到(位图图像​​)点之间绘制一条线. [英] C# Drawing a line from (bitmap image)dot to (bitmap image)dot.

查看:148
本文介绍了C#在(位图图像​​)点到(位图图像​​)点之间绘制一条线.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的读者,
我来这里有一个问题.
我一直在研究在表单上绘制点网格(6行8列)的代码.对我来说,很难理解如何在表单上绘制它,因为我对C#中的Graphics的知识非常贫乏,但最终还是可以工作.
接下来,我要做的是在鼠标单击事件上画一条从DOT到DOT的线.不幸的是,我无法提出一种好的方法.
我当时正在考虑创建一个List< point>以DOT作为项目,但没有得到进一步的解决.漂亮的人能帮我吗?
我添加了注释,以使读者更容易理解而不会造成任何脑损伤.你能帮我吗?

如果是这样,请参见下面的代码.
并先谢谢您!

Form1.cs:

Dear reader,
I came here with a problem.
I''ve been working days on a code that draws a grid of dots (6 rows, 8 columns) on the form. It was very hard for me to understand how to get it drawn on the form as my knowledge with Graphics in C# is very poor, but working eventually.
What I''m trying and wanting to do next is to draw a line from a DOT to DOT on mouse clicks events. Unfortunately I couldn''t came up with a good approach to do this.
I was thinking of creating a List<point> with a DOT as item, but didn''t get any further. Could anyone pretty please help me out?
I added comments to make it easier for the reader to understand without causing any braindamage. Could you pretty please help me?

If so, see below for my code.
And thank you in advance!

Form1.cs:

public partial class Form1 : Form
    {
        private GridDrawing drawing;
        //private Point point1 = new Point(); //First point
        //private Point point2 = new Point(); //Second point
        ////True if point1 must be updated
        ////False if point2 must be updated
        //private bool firstPoint = true;
        private int sizeOfDot;
        private int rows;
        private int columns;
        public Form1()
        {
            InitializeComponent();
            sizeOfDot = 10;     //The size of the dot
            rows = 6;           //The amount of rows for the matrix
            columns = 8;        //The amount of columns for the matrix
            Paint += new PaintEventHandler(Form_Paint);             //Handle the Paint event
            SizeChanged += new EventHandler(Form1_SizeChanged);     //Handle the SizeChanged event to force redraw the form
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);     //to avoid flickering
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);    //to avoid flickering
        }
        private void Form_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(Brushes.White, ClientRectangle);   //Fill the form in white
            drawing = new GridDrawing(this, rows, columns);             //Control, Rows, Columns
            foreach (var piece in drawing.Pieces)                           //Draws all the dots
            {
                e.Graphics.FillEllipse(Brushes.Black, (piece.Dot.X - sizeOfDot / 2),
                    (piece.Dot.Y - sizeOfDot / 2), sizeOfDot, sizeOfDot);   //Draws the dot
            }
        }
        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }
        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            //if (firstPoint)             //Update point1 or point2
            //{
            //    point1 = e.Location;
            //}
            //else
            //{
            //    point2 = e.Location;
            //}
            //firstPoint = !firstPoint;   //Change the bool value
            //Invalidate();               //ask to redraw
        }
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            Invalidate();
        }
    }



GridDrawing.cs:



GridDrawing.cs:

public class GridDrawing
{
    private int columns;
    private int rows;
    private int sizeOfDot;
    private List<GridPiece> pieces;
    //// private Point position;
    //private Point point1; //point1 to start drawing line from
    //private Point point2; //point2 to end drawing line from
    /// <summary>
    /// Constructs a grid
    /// </summary>
    /// <param name="ctrl"></param>
    /// <param name="rows"></param>
    /// <param name="columns"></param>
    /// <param name="sizeOfDot"></param>
    public GridDrawing(Control ctrl, int rows, int columns)
    {
        this.rows = rows;               // The amount of rows in the matrix.
        this.columns = columns;         // The amount of columns in the matrix.
        this.pieces = new List<GridPiece>();                // Initializes the List GridPieces
        float xOffset = (float)ctrl.ClientRectangle.Width / (columns + 1);  // Floating Point offset for X
        float yOffset = (float)ctrl.ClientRectangle.Height / (rows + 1);    // Floating Point offset for Y
        //Generate the dots
        for (int i = 0; i < rows; i++)          //Matrix with 6 rows
        {
            for (int j = 0; j < columns; j++)   //Matrix with 8 columns
            {
                PointF dot = new PointF((j + 1) * xOffset, (i + 1) * yOffset);  // Center of the dot
                GridPiece p = new GridPiece(dot);  // Creates a piece
                pieces.Add(p);                     // Puts the piece that has to be drawn in the List<GridPiece>pieces
            }
        }
    }
    public List<GridPiece> Pieces   //Property List<GridPiece>pieces
    {
        get { return this.pieces; }
    }
}



GridPiece.cs:



GridPiece.cs:

public class GridPiece
{
    private PointF dot;
    /// <summary>
    /// Constructor of GriedPiece
    /// </summary>
    /// <param name="bmpPic"></param>
    /// <param name="position"></param>
    public GridPiece(PointF dot)
    {
        this.dot = dot;
    }
    public PointF Dot
    {
        get { return dot; }
    }
}



PS
很抱歉,如果注释未正确显示在一行上.
这就是示例的外观.右侧的小点是绘制为网格的图像.
我不知道为什么网格上的点比原始文件大...


现在,已将代码编辑为我当前的代码.



PS
Sorry if the comments aren''t shown properly on one line.
This is how it looks like Example. The little dot on the right is the image thats been drawn as a grid.
Altho I''m not sure why the dots on the grid are bigger then the original file...


The code has now been edited to what I have currently.

推荐答案

确实需要使用图像吗?您不能直接在表格内绘制吗?

您可以使用MouseDown事件获取点击位置,并使用Paint事件重绘线条:

Is it really necessary to use an image? Can''t you draw directly inside your form?

You can use the MouseDown event to get the click position, and Paint event to redraw your line:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    //first point
    Point point1 = new Point();
    //second point
    Point point2 = new Point();
    //true if point1 must be updated
    //false if point2 must be updated
    bool firstPoint = true;
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        //draw the line
        e.Graphics.DrawLine(Pens.Black, point1, point2);
    }
    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        //update point1 or point2
        if (firstPoint)
            point1 = e.Location;
        else
            point2 = e.Location;
        //change the bool value
        firstPoint = !firstPoint;
        //ask to redraw
        Invalidate();
    }
}



-----------------

对您的评论:

是的,我是那个意思.
在您的示例中,您正在使用Bitmaps.除非您要将这些位图保存到文件中(或从文件中加载它们),否则没有必要.实际上,这使您的代码更加复杂.如果您的目标是在窗体内绘制圆和直线,则只需将所有绘制代码​​放入Paint处理程序中(如上所示),并使用DrawLineDrawEllipseGraphic类中的任何方法.这样会容易得多.

如果您不需要MouseDown处理程序,那么就算了吧,这只是为了展示如何更新工程图.重要的事情包括Invalidate强制重新绘制表单,Paint处理程序放置绘制代码,以及e.Graphics绘制.

---------------

这是一个如何绘制网格的示例:



-----------------

To your comment:

Yes I mean that.
In your example, you are using Bitmaps. Unless you want to save those bitmaps to a file (or load them from a file), there are not necessary. And actually it makes your code much more complicated. If your aim is drawing circles and lines inside your form, then just put all your drawing code in the Paint handler (as shown above) and use the DrawLine, DrawEllipse, or any method from the Graphic class. It will be much easier like that.

If you don''t need the MouseDown handler then forget about it, it was just to show how to update drawings. Important things are Invalidate to force the form to redraw, the Paint handler to put drawing code, and e.Graphics to draw.

---------------

Here is an example of how to draw your grid:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        //handle the Paint event
        Paint += new PaintEventHandler(Form1_Paint);
        //handle the SizeChanged event to force redraw the form
        SizeChanged += new EventHandler(Form1_SizeChanged);
        //to avoid flickering
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }
    //your grid parameters
    int rows = 5;
    int columns = 8;
    int sizeOfDot = 10;
    //all the drawings are there
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        //fill the form in white
        e.Graphics.FillRectangle(Brushes.White, ClientRectangle);
        //draw the dot
        float xOffset = (float)ClientRectangle.Width / (columns + 1);
        float yOffset = (float)ClientRectangle.Height / (rows + 1);
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < columns; j++)
            {
                //center of the dot
                PointF dot = new PointF((j + 1) * xOffset, (i + 1) * yOffset);
                //draw the dot
                e.Graphics.FillEllipse(Brushes.Black,
                    dot.X - sizeOfDot / 2, dot.Y - sizeOfDot / 2,
                    sizeOfDot, sizeOfDot);
            }
        //draw a line to connect 2 dots
        PointF dot1 = new PointF(4 * xOffset, 2 * yOffset);
        PointF dot2 = new PointF(2 * xOffset, 3 * yOffset);
        e.Graphics.DrawLine(Pens.Black, dot1, dot2);
    }
    //when the size of the form is changed, force a redraw
    private void Form1_SizeChanged(object sender, EventArgs e)
    {
        Invalidate();
    }
}



---------------------

要连接点,可以在Form_Paint的末尾添加类似的内容:



---------------------

To connect your dots, you can add something like that at the end of Form_Paint:

//draw the dots in this order (each value is an index in the Pieces list)
int[] sequence = new int[] { 1, 2, 3, 4, 12, 11, 19, 20, 21 };
//build a point list
PointF[] points = new PointF[sequence.Length];
for (int i = 0; i < sequence.Length; i++)
    points[i] = drawing.Pieces[sequence[i]].Dot;
//connect all points
e.Graphics.DrawLines(Pens.Black, points);


这篇关于C#在(位图图像​​)点到(位图图像​​)点之间绘制一条线.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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