我有一个带有停靠面板的WinForm。 我超越了Panel的Paint事件。 我有一行设置_graphics对象:
private Graphics _graphics;
在覆盖中我初始化_graphics对象:
private void GridPanel_Paint(object sender, PaintEventArgs e)
{
_graphics = e.Graphics;
<snip>
…
</snip>
}
这是愚蠢的部分,我可以在MouseMove等任何其他事件中使用这个_graphics对象吗?
答案 0 :(得分:3)
这取决于“使用”是什么意思。
Graphics
是一次性的。重新绘制后,控件处理Graphics
实例,该实例已传递到Paint
事件处理程序。从那时起,处置对象就没用了。但是缓存对该实例的引用是绝对合法的。
答案 1 :(得分:1)
您可以使用CreateGraphics
方法使用控件的图形对象,但当控件刷新时,您的绘画将消失。
所以最好根据某些逻辑在Paint
事件中绘制您需要的内容,然后每次控件刷新时,您的绘制逻辑都将应用,并且绘图将显示在您的控制。
例如当你想在MouseMove
事件中绘制一个矩形时,它足以将矩形存储在一个类成员变量中,并调用yourControl.Invalidate();
然后使用Paint
事件处理程序中的矩形并绘制它。 Invalidate
使控件重绘,因此您的绘画逻辑将会运行。
答案 2 :(得分:1)
是的,你可以在Paint/PaintBackground
事件之外使用图形,但你不应该也不需要它。
我的猜测是(假设你引用了MouseMove
)你希望在控件上发生特定事件时发生一些绘画;有几个解决方案:
示例1 - 注册事件处理程序
private void panel1_MouseMove(object sender, EventArgs e)
{
// forces paint event to fire for entire control surface
panel1.Refresh();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.....;
}
示例2 - 继承
class CustomControl : Control
{
public CustomControl()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
UpdateStyles();
}
protected override void OnMouseMove(EventArgs e)
{
base.OnMouseMove(e);
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics...;
}
}
备注强>
OnPaint/Paint
,就会处理e.Graphics,因此,设置对该对象的全局引用将毫无用处,因为一旦Paint事件完成,它将为null
。CreateGraphics()
方法/事件之外绝对需要Graphics
,则可以使用Paint/PaintBackground
,但不建议这样做。Paint/PaintBackground
自然会落入WinForms事件/渲染管道中,因此理想情况下应覆盖这些并适当地使用它们。答案 3 :(得分:1)
如果您想在MouseMove事件上重新绘制面板,请调用Invalidate()
方法并在Paint
事件上执行绘制逻辑。
Invalidate()
方法将面板标记为“脏”,并且绘制将由winforms消息循环引起。