C# 我如何调用绘画事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/952906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:07:51  来源:igfitidea点击:

How do I call paint event?

c#.netwinformsevents

提问by Ivan Prodanov

My program draws text on its panel,but if I'd like to remove the text I have to repaint.

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

How do I call(raise) the paint event by hand?

我如何手动调用(引发)paint 事件?

采纳答案by Matthew Vines

The Invalidate() Method will cause a repaint.

Invalidate() 方法将导致重绘。

MSDN Link

MSDN链接

回答by Otávio Décio

Call control.invalidate and the paint event will be raised.

调用 control.invalidate 将引发绘制事件。

回答by Brian

I think you can also call Refresh().

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

回答by Henk Holterman

In a method of your Form or Control, you have 3 choices:

在 Form 或 Control 的方法中,您有 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()

Normally, you would just call Invalidate()and let the system combine that with other Screen updates. If you're in a hurry you should call Refresh()but then you run the risk that it will be repainted several times consecutively because of other controls (especially the Parent) Invalidating.

通常,您只需调用Invalidate()并让系统将其与其他屏幕更新结合起来。如果你很着急,你应该打电话,Refresh()但你会冒着连续多次重绘的风险,因为其他控件(尤其是父控件)无效。

The normal way Windows (Win32 and WinForms.Net) handles this is to wait for the MessageQueueto run empty and then process all invalidated screen areas. That is efficient because when something changes that usually cascades into other things (controls) changing as well.

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

The most common scenario for Update() is when you change a property (say, label1.Text, which will invalidate the Label) in a for-loop and that loop is temporarily blocking the Message-Loop. Whenever you use it, you should ask yourself if you shouldn't be using a Thread instead. But the answer is't always Yes.

Update() 最常见的情况是当您在 for 循环中更改属性(例如 label1.Text,这将使 Label 无效)并且该循环暂时阻塞 Message-Loop 时。无论何时使用它,您都应该问问自己是否不应该使用 Thread。但答案并不总是肯定的。

回答by Simon Nunn

Refresh would probably also make for much more readable code, depending on context.

根据上下文,刷新可能还会产生更具可读性的代码。

回答by user2529145

I found the Invalidate()creating too much of flickering. Here's my situation. A custom control I am developing draws its whole contentsvia handling the Paintevent.

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

this.Paint += this.OnPaint;

This handler calls a custom routine that does the actual painting.

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

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

To simulate scrolling I want to repaint my control every time the cursor moves while the left mouse button is pressed. My first choice was using the Invalidate()like the following.

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

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

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

The control scrolls OK but flickersfar beyond any comfortable level. So I decided, instead of repainting the control, to call my custom DrawFrame()method directly after handling the MouseMoveevent. That produced a smooth scrolling with no flickering.

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

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

This approach may not be applicable to all situations, but so far it suits me well.

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

回答by TheNegative

use Control.InvokePaintyou can also use it for manual double buffering

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

回答by Izar Urdin

Maybe this is an old question and that′s the reason why these answers didn't work for me ... using Visual Studio 2019, after some investigating, this is the solution I've found:

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

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