【问题标题】:Drawing same shape in the same graphics method c#在相同的图形方法c#中绘制相同的形状
【发布时间】:2018-08-29 00:53:24
【问题描述】:

我一直在做一个简单的图形项目,我可以使用按钮绘制形状并编辑它们(调整大小和其他东西)。我已经能够绘制不同的形状,但我的问题是我无法再次绘制相同的形状。它只更新之前相同形状的参数。

例如,我尝试绘制一个矩形,然后我想以不同的大小再次绘制,矩形改变它的大小而不是创建一个新的。

这是我的代码:

形状类

class ShapeClass
{
    public int x { get; set; }
    public int y { get; set; }
    public int width { get; set; }
    public int height { get; set; }
    public Pen color { get; set; }
    public string Shape { get; set; }
 }

绘图类

class Draw:ShapeClass
    {
    public void DrawRectangle(PaintEventArgs e)
        {
        e.Graphics.DrawRectangle(color, new Rectangle(x, y, width, height));
    }
    public void DrawSquare(PaintEventArgs e)
    {
        e.Graphics.DrawRectangle(color, new Rectangle(x, y, width, height));
    }
    public void DrawCircle(PaintEventArgs e)
    {
        e.Graphics.DrawEllipse(color, new Rectangle(x,y,width,height));
    }
    public void DrawEllipse(PaintEventArgs e)
    {
        e.Graphics.DrawEllipse(color, new Rectangle(x, y, width, height));
    }

绘画活动

    public void PaintRect(object sender, PaintEventArgs e)
    {
        //Calls Draw class and sets the parameters of the Shape.
        Draw d = new Draw();
        d.x = rX;
        d.y = rY;
        d.width = rW;
        d.height = rH;
        rC = new Pen(Color.Red, 2);
        d.color = rC;
        d.DrawRectangle(e);
    }
    public void PaintSquare(object sender, PaintEventArgs e)
    {
        //Calls Draw class and sets the parameters of the Shape.
        Draw d = new Draw();
        d.x = sX;
        d.y = sY;
        d.width = sW;
        d.height = sH;
        d.color = new Pen(Color.Red, 2);
        //d._Rectangle.Add(new Rectangle(sX,sY,sW,sH));
        d.DrawSquare(e);
    }
    public void PaintCircle(object sender, PaintEventArgs e)
    {
        //Calls Draw class and sets the parameters of the Shape.
        Draw d = new Draw();
        d.x = cX;
        d.y = cY;
        d.width = cW;
        d.height = cH;
        d.color = new Pen(Color.Red, 2);
        d.DrawCircle(e);
    }
    public void PaintEllipse(object sender, PaintEventArgs e)
    {
        //Calls Draw class and sets the parameters of the Shape.
        Draw d = new Draw();
        d.x = eX;
        d.y = eY;
        d.width = eW;
        d.height = eH;
        d.color = new Pen(Color.Red, 2);
        d.DrawEllipse(e);
    }

【问题讨论】:

  • 我想我们需要看看ShapeClass的定义,看看你是如何定义各种位置和大小参数的。
  • 编辑了正文。
  • 我显然遗漏了一些东西。你如何定义cXcYcWcH
  • 每次引发Paint 事件时,您之前绘制的所有内容都会被删除。如果要绘制多个形状,则必须将这些形状存储在类级别的列表中,然后在每个 Paint 事件上绘制该列表中的所有内容。您应该有一个 Paint 事件处理程序来绘制列表中的每个项目,然后添加一个新形状,即向该列表添加一个项目,然后通过调用 Refresh 强制重新绘制。
  • 在被告知要做什么后几秒钟内您无法编写正确的代码这一事实并不表明您不能这样做。把一些想法放进去。尽你最大的努力,然后,如果它不起作用,用新代码更新你的问题,我们可以提供进一步的帮助。简而言之,总是先为自己做你能做的事,只有在你真正陷入困境时才寻求更多帮助。假设你做不到并要求别人为你编写代码并不是让你自己编写代码更好的方法。失败是学习不可或缺的一部分,因此失败的可能性不是不尝试的理由。

标签: c# winforms graphics


【解决方案1】:

让我们看一下您的 PaintCircle 事件处理程序:

public void PaintCircle(object sender, PaintEventArgs e)
{
    //Calls Draw class and sets the parameters of the Shape.
    Draw d = new Draw();
    d.x = cX;
    d.y = cY;
    d.width = cW;
    d.height = cH;
    d.color = new Pen(Color.Red, 2);
    d.DrawCircle(e);
}

相当直截了当,但看起来很像您在表单上定义了一组值:cXcYcWcH。您在其他 Paint... 方法中有类似的变量。

几乎可以肯定,您正在调整这些变量并重新绘制画布。这通常会擦除现有内容并完全重绘,这意味着您现有的图像将被删除,而您的“新”形状将是被绘制的那个。

有几种方法可以解决这个问题:

  1. 使图像持久化

您可以为您的画布创建一个合适形状的System.Drawing.Bitmap 对象,在Bitmap 上完成所有绘图,然后更新显示。

这样做的缺点是,如果您愿意,您无法返回并更改现有对象。一旦您在图像上绘图,它就会永久更改为新形状。

如果您要这样做,您可能应该考虑使用多个Bitmap 图像,以便您可以通过从列表中获取先前图像来撤消。当您开始绘制操作时,复制当前的Bitmap 并将副本放入您的撤消列表中。要撤消,请从该列表中拉出最后一项并将您的工作 Bitmap 替换为它。不要忘记整理您的撤消列表,以确保您不会使用所有内存。

  1. 维护对象列表并根据需要重新绘制整个列表

为此,您需要构建一些更有趣的Shape 类。

这里有一个简单的示例...

public abstract class Shape
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public Pen LineColor { get; set; } = Pens.Red;
    public Brush FillColor { get; set; } = null;

    public abstract void Draw(Graphics g);
}

public class EllipseShape : Shape
{
    public override void Draw(Graphics g)
    {
        if (FillColor != null)
            g.FillEllipse(FillColor, X, Y, Width, Height);
        g.DrawEllipse(LineColor, X, Y, Width, Height);
    }
}

public class RectangleShape : Shape
{
    public override void Draw(Graphics g)
    {
        if (FillColor != null)
            g.FillRectangle(FillColor, X, Y, Width, Height);
        g.DrawRectangle(LineColor, X, Y, Width, Height);
    }
}

...等等。

在您的主窗体上,您可以添加一个List<Shape> 来保存您的形状,然后在画布的OnPaint 事件中 - 无论您使用哪种类型的画布 - 您都可以这样做:

private void MainForm_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    foreach (var shape in shapeList)
        shape.Draw(g);
}

【讨论】:

  • 工作很忙,直到一天结束才发布。无论如何希望它有用:)
猜你喜欢
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 2011-10-14
  • 2019-05-11
  • 2014-04-13
相关资源
最近更新 更多