【问题标题】:Why does this not draw anything? [closed]为什么这不画任何东西? [关闭]
【发布时间】:2017-07-12 03:56:24
【问题描述】:

我的代码中有以下 if 语句:

//global variables
int x1;
int y1;
int x2;
int y2;
int counter = 0;

private void pictureBox1_Click(object sender, EventArgs e)
{
    if (radioButtonDrawLine.Checked)
    {
        if (counter == 0)
        {
            x1 = Cursor.Position.X;
            y1 = Cursor.Position.Y;
            counter++;                        
        }    
        else
        {
            x2 = Cursor.Position.X;
            y2 = Cursor.Position.Y;

            if (counter == 1)
            {
                Graphics g = CreateGraphics();
                g.DrawLine(Pens.Black, x2, y2, x1, y1);
            }
            counter = 0;
        }
    }
}

我应该在我的图片框上单击两次,每次单击时它都会保存 x 和 y。在第二次单击时,应在两个坐标之间绘制一条线。 但是这不起作用,我不知道为什么。谁能告诉我怎么了?

【问题讨论】:

  • radioButtonDrawLine.Checked == true?
  • 还是不行。我认为不使用“== true”应该是一样的

标签: c# winforms system.drawing


【解决方案1】:

您的代码有两个主要问题。

首先,您在表单上调用CreateGraphics,而不是在图片框上调用 - 因此,如果您确实绘制到了正确的位置,则绘图将被图片框隐藏。

其次,您的坐标已关闭,因为Cursor.Position 返回屏幕坐标,而不是相对于您正在绘制的控件的坐标。但这已经是不必要的了——你首先不应该使用Click 事件,而应该使用MouseUpClick 是一个不同的动作,它根本不需要使用指针设备(例如,按下按钮上的空格)。你想处理鼠标点击,所以使用鼠标事件。作为奖励,您将在事件处理程序的参数中获得单击的本地坐标 :)

最后,如果你想让图像持久化,我建议不要直接绘制到图片框图形对象,而是创建一个内存位图来保存绘图,让图片框重新绘制为它认为合适。否则,任何导致图片框重绘的东西也会清除你到目前为止绘制的任何东西。

【讨论】:

    【解决方案2】:

    您应该在 Paint 事件中进行绘图。像下面这样的东西应该可以工作:

    //global variables
    private Point? p1;
    private Point? p2;
    private int counter = 0;
    
    private void pictureBox1_Click(object sender, EventArgs e)
    {
        if (radioButtonDrawLine.Checked)
        {
            if (counter == 0)
            {
                p1 = pictureBox1.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y));
                counter++;
            }
            else
            {
                p2 = pictureBox1.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y));
                pictureBox1.Refresh();
                counter = 0;
            }
        }
    }
    
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        if (p1.HasValue && p2.HasValue)
        {
            e.Graphics.DrawLine(Pens.Black, p1.Value.X, p1.Value.Y, p2.Value.X, p2.Value.Y);
        }
    }
    

    pictureBox1.Refresh() 调用是在创建第二个点后强制重新绘制。请注意,我还使用 Point 结构而不是 int 来存储坐标,因为这样可以将坐标保持在逻辑组中,并且更清楚它们是什么。

    【讨论】:

    • 如果您采用这种方式,请在捕获坐标后立即执行PointToClient,而不是在Paint 事件中。与此同时,控件可能已经移动,这会使线条也移动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    • 2013-07-28
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多