动态改变图形矩形的颜色
Change color of graphic rectangle dynamically
我写了一个c#class,里面有图形。
这就是我构建 class 并绘制矩形的方式。它完美运行:
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);
有一个无效的参数。
好的,让我们从'drawRectangle' class开始。它有足够的数据来创建一个简单的 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();
}
更新:
上面的 class 是一个简单的开始,展示了如何封装 'Rectangle' class 需要的东西;它并不意味着完美!
这是它的一个缺陷:它不太关心分散 责任 的最佳方式。它把绘制矩形的负担放在控件上,如果您有更复杂的绘图代码和更多控件,则每个控件都必须学习更复杂的代码。这个不好。相反,责任应该由矩形 class 承担。控件应该只告诉他们自己画..
这是一个更新的 class 可以做到这一点。作为一个更复杂的绘图,它也可以绘制填充的矩形..:[=43=]
版本 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
确实只是'transparent black' (0,0,0, 0),颜色比较特殊:NamedColors
以及KnownColors
,包括Color.Empty
总是比较假 到正常颜色。要进行真实的颜色比较,必须转换为 'normal' 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
代码中的比较是安全的。
我写了一个c#class,里面有图形。 这就是我构建 class 并绘制矩形的方式。它完美运行:
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);
有一个无效的参数。
好的,让我们从'drawRectangle' class开始。它有足够的数据来创建一个简单的 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();
}
更新:
上面的 class 是一个简单的开始,展示了如何封装 'Rectangle' class 需要的东西;它并不意味着完美!
这是它的一个缺陷:它不太关心分散 责任 的最佳方式。它把绘制矩形的负担放在控件上,如果您有更复杂的绘图代码和更多控件,则每个控件都必须学习更复杂的代码。这个不好。相反,责任应该由矩形 class 承担。控件应该只告诉他们自己画..
这是一个更新的 class 可以做到这一点。作为一个更复杂的绘图,它也可以绘制填充的矩形..:[=43=]
版本 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
确实只是'transparent black' (0,0,0, 0),颜色比较特殊:NamedColors
以及KnownColors
,包括Color.Empty
总是比较假 到正常颜色。要进行真实的颜色比较,必须转换为 'normal' 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
代码中的比较是安全的。