动态更改图形矩形的颜色

时间:2016-08-22 06:23:28

标签: c# graphics drawrectangle

我写了一个c#类,里面包含图形。 这就是我构建类并绘制矩形的方法。它完美地运作:

public Graphics shape;
public Rectangle rc;

// constructor
public CLASS_NAME(Graphics formGraphics)
{
    this.shape = formGraphics;
}

public void draw(int x, int y, int w, int h)
{
    SolidBrush myBrush = new SolidBrush(Color.Red);
    this.rc = new Rectangle(x, y, w, h);
    this.shape.FillRectangle(myBrush, rc);

    myBrush.Dispose();
}

然后我想为对象添加一个新方法以改变颜色,但是当我调用它时没有任何反应:

public void change_color()
{
    SolidBrush myBrush = new SolidBrush(Color.Yellow);
    this.shapeFillRectangle(myBrush, rc);
    myBrush.Dispose();
}

我也尝试过:rc.Fill =但是VS并没有将rc.Fill视为有效的方法。

  • 我得到的错误:它表示在change()方法中,此行:this.shapeFillRectangle(myBrush, rc);有一个无效的参数。

1 个答案:

答案 0 :(得分:1)

好的,让我们从'drawRectangle'类开始吧。它有足够的数据来创建简单的Pen,包含Rectangle以及对其将使用的Control的引用。

我添加了ToString覆盖,因此我们可以在其中显示所有属性,例如ListBox ..

版本1

public class DrawRectangle
{
    public Color color { get; set; }
    public float width { get; set; }
    public Rectangle rect { get; set; }
    public Control surface { get; set; }

    public DrawRectangle(Rectangle r, Color c, float w, Control ct)
    {
        color = c;
        width = w;
        rect = r;
        surface = ct;
    }

    public override string ToString()
    {
        return rect.ToString() + " (" + color.ToString() + 
               " - " + width.ToString("0.00") + ") on " + surface.Name;
    }
}

接下来我们需要一个矩形列表:

public List<DrawRectangle> rectangles = new List<DrawRectangle>();

现在让我们通过点击按钮将它们添加到循环中:

private void buttonAddLoop_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
        rectangles.Add(new DrawRectangle(new Rectangle(i * 30, i * 30, 22, 22), 
                                            Color.Black, 3.5f, drawPanel1));
    drawPanel1.Invalidate();
}

请注意我如何使我想要的控件无效Invalidating它! (您也可以使用Form,因为Form继承自Control。)

为此,我们需要编写每个需要绘制一些矩形的控件的Paint事件;我只使用Panel drawPanel1

private void drawPanel1_Paint(object sender, PaintEventArgs e)
{
    foreach (DrawRectangle dr in rectangles)
    {
        if (dr.surface == sender)
        {
            using (Pen pen = new Pen(dr.color, dr.width))
                e.Graphics.DrawRectangle(pen, dr.rect);
        }
    }
}

现在我们可以更改任何DrawRectangles,也许可以点击另一个按钮:

private void buttonChangeButton_Click(object sender, EventArgs e)
{
    rectangles[3].color = Color.Red;
    rectangles[6].width = 7f;
    drawPanel1.Invalidate();
}

enter image description here

<强>更新

上面的类是一个简单的开始,展示了如何封装'Rectangle'类需要的东西;它并不意味着完美!

这是一个缺陷:它并没有真正关心传播责任的最佳方式。它把绘制矩形的负担放在控件上,如果你有更复杂的绘图代码和更多的控件,他们每个都必须学习更复杂的代码。这个不好。相反,责任应该留在Rectangle类。控件应该只告诉他们画画。

这是一个更新的类,可以做到这一点。作为一个更复杂的绘图,它也可以绘制填充的矩形..:

第2版

public class DrawRectangle
{
    public Color color { get; set; }
    public float width { get; set; }
    public Color fillColor { get; set; }
    public Rectangle rect { get; set; }
    public Control surface { get; set; }

    public DrawRectangle(Rectangle r, Color c, float w, Color fill, Control ct  )
    {
        color = c;
        width = w;
        fillColor = fill;
        rect = r;
        surface = ct;
    }

    public DrawRectangle(Rectangle r, Color c, float w,  Control ct) 
    : this. DrawRectangle(r, c, w, Color.Empty, ct)  {}

    public override string ToString()
    {
        return rect.ToString() + " (" + color.ToString() + 
               " - " + width.ToString("0.00") + ")";
    }

    public void Draw(Graphics g)
    {
        if (fillColor != Color.Empty) 
            using (SolidBrush brush = new SolidBrush(fillColor))
                 g.FillRectangle(brush, rect);
        if (color != Color.Empty)
            using (Pen pen = new Pen(color, width)) g.DrawRectangle(pen, rect);
    }
}

它使用第二种颜色来确定填充。 (我没有在ToString方法中添加填充颜色。)它将颜色与特殊颜色值Color.Empty进行比较,以确定应该和不应该绘制的颜色。

创建新矩形的循环现在可以包含填充颜色。如果没有,将调用旧的构造函数,现在将填充颜色设置为Color.Empty

以下是Paint事件的简单程度:

private void drawPanel1_Paint(object sender, PaintEventArgs e)
{
    foreach (DrawRectangle dr in rectangles)
        if (dr.surface == sender) dr.Draw(e.Graphics);
}

要填写一些矩形,我们现在可以写:

rectangles[2].fillColor = Color.Fuchsia;

enter image description here

<强>除了:

注意颜色比较:这不明显,但颜色Color.Empty实际上只是'透明黑'(0,0,0,0),颜色比较是特殊的NamedColors以及KnownColors,包括Color.Empty始终比较错误与正常颜色。要进行真正的颜色比较,必须转换为“正常”Color

bool ok=Color.FromArgb(255,255,255,255) == Color.White;  // false
bool ok=Color.FromArgb(255,255,255 255) == Color.FromArgb(Color.White.ToArgb()); // true

因此Draw代码中的比较是安全的。