我写了一个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);
有一个无效的参数。答案 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();
}
<强>更新强>
上面的类是一个简单的开始,展示了如何封装'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;
<强>除了:强>
注意颜色比较:这不明显,但颜色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
代码中的比较是安全的。