Winforms等待绘制直到添加控件

时间:2010-01-15 18:09:06

标签: c# winforms controls draw

  

可能重复:
  How do I suspend painting for a control and its children?

我在一个表单中添加了几百个控件,然后表单闪烁,直到它完成,因为它添加了每个控件,无论如何都要阻止它?

3 个答案:

答案 0 :(得分:4)

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

How do I suspend painting for a control and its children?

(为方便起见而复制的答案:最初来自: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();
    }
}

有关此问题的更全面的讨论 - 谷歌的C#和WM_SETREDRAW,例如。

C# Jitter

Suspending Layouts

答案 1 :(得分:2)

可能希望使用Form

的SuspendLayout和ResumeLayout属性包围您的代码

this.SuspendLayout();

//创建控件

this.ResumeLayout(真);

答案 2 :(得分: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();
    }
}