一尘不染

如何在WinForms中绘制形状

c#

我正在尝试编写类似绘画的程序。您可以通过选择所需的形状来绘制填充的形状,单击图片框并拖动鼠标以获取所需的大小。但是时候我能拖发生。当我使用时refresh();,先前绘制的shapes会自行删除。如何绘制填充形状?

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);
            }
        }

    }

阅读 326

收藏
2020-05-19

共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以仅使更改后的屏幕区域无效,而不会使旧矩形和新矩形无效。

2020-05-19