我可以在除 Paint 事件之外的任何其他事件中使用 Graphics 对象吗?

Can I use Graphics object in any other event than Paint event?

我有一个带有停靠面板的 WinForm。 我覆盖了 Panel 的 Paint 事件。 我有一行设置 _graphics 对象:

private Graphics _graphics;

在覆盖中我初始化了 _graphics 对象:

private void GridPanel_Paint(object sender, PaintEventArgs e)
{
    _graphics = e.Graphics;

    <snip>
    …
    </snip>
}

愚蠢的部分来了,我可以在 MouseMove 等任何其他事件中使用这个 _graphics 对象吗?

这取决于你所说的"use"是什么意思。

Graphics是一次性的。重新绘制后,控件会处理 Graphics 实例,该实例已传递到 Paint 事件处理程序。从那时起,处置的对象是无用的。但是缓存对该实例的引用是绝对合法的。

您可以在需要的地方使用 CreateGraphics 方法使用控件的图形对象,但是当控件刷新时,您的绘图将消失。

所以最好根据一些逻辑在Paint事件中绘制你需要的东西,然后每次控件刷新时,你的绘制逻辑将应用并且绘图将显示在您的控件上。

例如当你想在你的MouseMove事件中绘制一个矩形时,将矩形存储在class成员变量中就足够了,并且调用 yourControl.Invalidate(); 然后使用 Paint 事件处理程序中的矩形并绘制它。 Invalidate 使控件重绘,因此您的绘画逻辑将 运行。

是的,您可以在 Paint/PaintBackground 事件之外使用 Graphics,但您不需要,也不建议这样做。

我的猜测是(假定您引用了 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...;
    }
}

注释

  1. 一旦 OnPaint/Paint 被调用,e.Graphics 将被释放,因此,设置对该对象的全局引用将毫无用处,因为一旦您的 Paint 事件发生,它将成为 null完成。
  2. 如果您在 Paint/PaintBackground methods/events 之外绝对需要 Graphics,则可以使用 CreateGraphics(),但不建议这样做。
  3. Paint/PaintBackground 自然地落入 WinForms event/rendering 管道,因此您最好覆盖这些并适当地使用它们。

如果您想在 MouseMove 事件上重绘面板,请调用 Invalidate() 方法并在 Paint 事件上执行绘制逻辑。

Invalidate()方法标记面板"dirty",绘画将由winforms消息循环引起。