Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WinForms中绘制形状_C#_Winforms - Fatal编程技术网

C# 如何在WinForms中绘制形状

C# 如何在WinForms中绘制形状,c#,winforms,C#,Winforms,我正试着编写类似绘画的程序。通过选择所需形状,单击picturebox并拖动鼠标以获得所需大小,可以绘制填充形状。但当我拖动时,会发生这种情况。当我使用refresh()时,先前绘制的形状会删除自身。我应该做什么来绘制填充形状 private void CizimPicture_MouseDown(object sender, MouseEventArgs e) { Cursor = Cursors.Cross; if (e.Button == Mouse

我正试着编写类似绘画的程序。通过选择所需形状,单击picturebox并拖动鼠标以获得所需大小,可以绘制填充形状。但当我拖动时,会发生这种情况。当我使用
refresh()时,先前绘制的形状会删除自身。我应该做什么来绘制填充形状

private void CizimPicture_MouseDown(object sender, MouseEventArgs e)
    {
        Cursor = Cursors.Cross;
        if (e.Button == MouseButtons.Left)
        {
            cizim = true;
        }
        X1 = e.X;
        Y1 = e.Y;
    }

    private void CizimPicture_MouseUp(object sender, MouseEventArgs e)
    {
        Cursor = Cursors.Default;
        cizim = false;
    }

    private void CizimPicture_MouseMove(object sender, MouseEventArgs e)
    {
        if (!cizim) return;

        if (cizim == true)
        {
            X = e.X;
            Y = e.Y;
            X2 = (e.X - X1);
            Y2 = (Y1 - e.Y);

            if (dikdörtgen == true)
            {
                resmim.FillRectangle(renk.Brush, X1, Y1, X2, -Y2);
            }
            if (elips == true)
            {
                resmim.FillEllipse(renk.Brush, X1, Y1, X2, -Y2);
            }
        }

    }

我寻找既简单又有效的示例代码,但没有找到任何东西。您不需要屏幕外位图或
CreateGraphics
,但您需要按照Eric的建议处理跟踪鼠标位置、在屏幕上绘制以及将绘制的形状添加到形状列表中。要处理交互式图形,需要在窗体处理程序中存储鼠标状态、初始单击位置和当前矩形:

bool mouseDown;
Point clickPos;
Rectangle rect;
然后,当用户单击时,记住初始位置:

private void MouseDown(object sender, MouseEventArgs e)
{
    mouseDown = true;
    clickPos = e.Location;
    rect = new Rectangle(clickPos, new Size(0, 0));
}
当用户向下拖动鼠标时,创建一个包含起始位置和当前位置的矩形:

private void MouseMove(object sender, MouseEventArgs e)
{
    if (mouseDown)
    {
        this.Invalidate(rect);
        if (e.Location.X > clickPos.X && e.Location.Y > clickPos.Y)
        {
            rect = new Rectangle(clickPos.X, clickPos.Y, e.Location.X - clickPos.X, e.Location.Y - clickPos.Y);
        }
        else if (e.Location.X > clickPos.X && e.Location.Y < clickPos.Y)
        {
            rect = new Rectangle(clickPos.X, e.Location.Y, e.Location.X - clickPos.X, clickPos.Y - e.Location.Y);
        }
        else if (e.Location.X < clickPos.X && e.Location.Y < clickPos.Y)
        {
            rect = new Rectangle(e.Location.X, e.Location.Y, clickPos.X - e.Location.X, clickPos.Y - e.Location.Y);
        }
        else if (e.Location.X < clickPos.X && e.Location.Y > clickPos.Y)
        {
            rect = new Rectangle(e.Location.X, clickPos.Y, clickPos.X - e.Location.X, e.Location.Y - clickPos.Y);
        }

        this.Invalidate(rect);
    }
}
Windows窗体中最重要的规则是:仅在绘制事件中绘制到屏幕。切勿在
MouseMoved
事件中绘制:

private void Paint(object sender, PaintEventArgs e)
{
    e.Graphics.FillRectangle(Brushes.DarkGray, rect);
}

完成此操作后,创建一个表单
列表
,并在
MouseUp
事件中添加当前矩形,并在
绘制
事件中绘制所有矩形。您可能还希望将图形剪裁到正在绘制的面板或窗口中。您还可以在
MouseMoved
中进行一些优化,以仅使更改的屏幕区域无效,而不是使新旧矩形都无效。

该程序正在执行它应该执行的操作;当你重画屏幕时,你必须告诉它,如果你想重画一些特定的东西,你应该重画什么。如果你不让它重画任何东西,那么结果就是什么都没有重画。如果你想在重画屏幕时重画一些东西,那么就编写这样做的代码。我认为你需要记住迄今为止已经绘制的所有形状,以便在调用refresh时可以重画它们,以及正在绘制的任何形状的位置。在紧要关头,你可以把你的形状绘制到位图上,然后直接显示出来,但这对你正在绘制的形状来说是不好的。Rup是正确的。通常,您要做的是记住位图中屏幕的先前状态,绘制该状态,然后在位图顶部绘制新形状。或者,您可以记住绘制的每个形状,然后在重新绘制屏幕时按正确的顺序重新绘制。我不知道如何将我的形状绘制成位图并再次显示。我试着用Paint handler而不是MouseMove来绘制我的形状,但没有成功,因为我无法获得坐标。事实上,我对编程相当陌生。如果我说的是不合理的话,对不起。请参阅和,以获取绘图更新/橡皮筋形状以及从形状数据列表中绘图的示例。。
private void Paint(object sender, PaintEventArgs e)
{
    e.Graphics.FillRectangle(Brushes.DarkGray, rect);
}