如何在WinForms中绘制形状

时间:2018-04-23 22:55:22

标签: c# winforms

我试图编写类似绘画的程序。您可以通过选择所需的形状来绘制填充的形状,单击图片框并拖动鼠标以获得所需的大小。但是当我拖动时THIS会发生。当我使用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);
            }
        }

    }

1 个答案:

答案 0 :(得分:1)

我查找了既简单又有效且没有找到任何内容的示例代码。您不需要屏幕外位图或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);
    }
}

当用户释放鼠标时,请停止绘图:

private void MouseUp(object sender, MouseEventArgs e)
{
    mouseDown = false;
}

Windows窗体中最重要的#1规则是:仅绘制到Paint事件中的屏幕。永远不要画在MouseMoved事件中:

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

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