如何检查调整大小是否仍在进行OnResize事件?

Kri*_*oks 1 c# events controls resize redraw

我需要在调整大小后重绘一个控件,而不是在调整大小时重新调整它,因为它需要花费大量时间来重绘控件,这会浪费大量资源.

我的控件继承了Control类,我正在覆盖OnResize事件.

PS: OnSizeChanged绝对一样

Aar*_*ght 8

让我提出这个问题的另一种观点:

问题不一定是"用户仍在调整控件的大小".真正的问题是控件的重新调整大小比重绘时间更长.

如果将问题定义为吞吐量之一,则更容易解决.事实上,Bebop对他的回答有正确的想法,但我认为我们可以做得更好:

public class MyControl : Control
{
    private TimeSpan paintTime = 250;   // Time to paint, default=250ms
    private TimeSpan resizeTime = 100;  // Time to update layout, default=100ms

    protected override void OnPaint(PaintEventArgs pe)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        // Do your painting here, or call base.OnPaint
        sw.Stop();
        paintTime = sw.Elapsed;
    }

    protected override void OnResize(EventArgs e)
    {
        // The "Stop" is not redundant - it will force the timer to "reset"
        // if it is already running.
        resizeTimer.Stop();
        base.OnResize(e);
        resizeTimer.Interval =
            (int)(paintTime.TotalMilliseconds + resizeTime.TotalMilliseconds);
        resizeTimer.Start();
    }

    private void UpdateSize()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        // Resizing code goes here
        sw.Stop();
        resizeTime = sw.Elapsed;
    }

    private void resizeTimer_Tick(object sender, EventArgs e)
    {
        resizeTimer.Stop();
        UpdateSize();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的想法是让控制主动自行分析; 如果你在慢速机器上运行它或者机器运行缓慢,那么这将减慢它的重绘速度.如果你在最前沿的硬件上运行它,那么它可能根本不必跳过任何重绘.这实际上是您经常在设备模拟器中看到的那种相当简单的"自动跳帧"算法.

要清楚,我没有反对nobugz倡导的方法; 我选择这个的唯一原因是逻辑是完全独立的,而暴露一个Resizing属性(或者更恰当地命名EnableFullPaint)取决于消费者知道并正确使用它 - 而且,它阻止任何重新调整整个调整大小的持续时间,这可能会导致应用程序"感觉"错误 - 用户在调整大小操作期间不会期望空白/无意义的屏幕.

我使用了两种方法,但它们都有效; 哪一个最适合您取决于您​​的要求.我建议你尝试一下,看看它对你有多好,如果它成为问题或不是你想要的,那么请使用nobugz的回答.