1

可能重复:
如何暂停控件及其子项的绘制?

我正在向一个表单添加几百个控件,并且表单在添加每个控件时闪烁,直到它完成,有没有办法阻止这个?

4

3 回答 3

4

答案与这个问题的答案相同:

如何暂停控件及其子控件的绘制?

(为方便起见复制了答案:最初来自:https ://stackoverflow.com/users/36860/ng5000 )

在我之前的工作中,我们一直在努力让我们丰富的 UI 应用程序能够立即流畅地绘制。我们使用的是标准的 .Net 控件、自定义控件和 devexpress 控件。

经过大量谷歌搜索和反射器使用后,我遇到了 WM_SETREDRAW win32 消息。这确实会在您更新控件时停止绘图,并且可以将 IIRC 应用于父/包含面板。

这是一个非常简单的类,演示如何使用此消息:

class DrawingControl
{
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

    private const int WM_SETREDRAW = 11; 

    public static void SuspendDrawing( Control parent )
    {
        SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
    }

    public static void ResumeDrawing( Control parent )
    {
        SendMessage(parent.Handle, WM_SETREDRAW, true, 0);
        parent.Refresh();
    }
}

对此有更全面的讨论 - google for C# 和 WM_SETREDRAW,例如

C# 抖动

暂停布局

于 2010-01-15T18:20:43.590 回答
2

可能想用 Form 的 SuspendLayout 和 ResumeLayout 属性包围你的代码

this.SuspendLayout();

//创建控件

this.ResumeLayout(true);

于 2010-01-15T18:17:30.263 回答
2

以下是 ng5000 的相同解决方案,但不使用 P/Invoke。

public static class SuspendUpdate
{
    private const int WM_SETREDRAW = 0x000B;

    public static void Suspend(Control control)
    {
        Message msgSuspendUpdate = Message.Create(control.Handle, WM_SETREDRAW, IntPtr.Zero,
            IntPtr.Zero);

        NativeWindow window = NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(ref msgSuspendUpdate);
    }

    public static void Resume(Control control)
    {
        // Create a C "true" boolean as an IntPtr
        IntPtr wparam = new IntPtr(1);
        Message msgResumeUpdate = Message.Create(control.Handle, WM_SETREDRAW, wparam,
            IntPtr.Zero);

        NativeWindow window = NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(ref msgResumeUpdate);

        control.Invalidate();
    }
}
于 2011-06-10T04:39:53.947 回答