我怎么称油漆事件?

时间:2009-06-04 20:28:21

标签: c# .net winforms events

我的程序在其面板上绘制文字,但如果我想删除文本,我必须重新绘制。

如何手动调用(加注)绘画事件?

8 个答案:

答案 0 :(得分:86)

在表单或控件的方法中,您有3个选择:

this.Invalidate();  // request a delayed Repaint by the normal MessageLoop system    
this.Update();      // forces Repaint of invalidated area 
this.Refresh();     // Combines Invalidate() and Update()

通常,您只需调用Invalidate()并让系统将其与其他屏幕更新结合使用。如果你赶时间,你应该致电Refresh(),但由于其他控件(特别是父母)无效,你会冒着连续几次重新粉刷的风险。

Windows(Win32和WinForms.Net)处理此问题的正常方法是等待MessageQueue运行为空,然后处理所有无效的屏幕区域。这是有效的,因为当某些变化通常会逐渐变为其他事物(控件)时也会发生变化。

Update()最常见的情况是在for循环中更改属性(例如,label1.Text,这将使Label无效)并且该循环暂时阻止消息循环。无论何时使用它,您都应该问自己是否应该使用线程。但答案并非总是如此。

答案 1 :(得分:42)

Invalidate()方法将导致重绘。

MSDN Link

答案 2 :(得分:6)

我发现 Invalidate()创建了太多的闪烁。这是我的情况。我正在开发的自定义控件通过处理 Paint 事件来绘制其整个内容

this.Paint += this.OnPaint;

此处理程序调用执行实际绘制的自定义例程。

private void OnPaint(object sender, PaintEventArgs e)
{
    this.DrawFrame(e.Graphics);
}

模拟滚动我想在每次按下鼠标左键时光标移动时重新绘制控件。我的第一选择是使用 Invalidate(),如下所示。

private void RedrawFrame()
{
    var r = new Rectangle(
        0, 0, this.Width, this.Height);

    this.Invalidate(r);
    this.Update();
}

控件滚动正常,但闪烁远远超出任何舒适的等级。所以我决定在处理 MouseMove 事件后直接调用我的自定义 DrawFrame()方法,而不是重新绘制控件。这产生了平滑的滚动,没有闪烁。

private void RedrawFrame()
{
    var g = Graphics.FromHwnd(this.Handle);
    this.DrawFrame(g);
}

这种方法可能并不适用于所有情况,但到目前为止它很适合我。

答案 3 :(得分:5)

我想你也可以打电话给Refresh()

答案 4 :(得分:4)

调用control.invalidate并引发paint事件。

答案 5 :(得分:3)

刷新可能还会产生更易读的代码,具体取决于上下文。

答案 6 :(得分:2)

也许这是一个古老的问题,这就是为什么这些答案对我不起作用的原因...使用Visual Studio 2019,经过一些调查,这是我找到的解决方案:

this.InvokePaint(this, new PaintEventArgs(this.CreateGraphics(), this.DisplayRectangle));

答案 7 :(得分:0)

使用Control.InvokePaint您也可以将其用于手动双缓冲