代码之家  ›  专栏  ›  技术社区  ›  T. Stone

WinForms等待绘制,直到添加控件[重复]

  •  1
  • T. Stone  · 技术社区  · 15 年前

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

    我正在向窗体添加几百个控件,窗体在添加每个控件时一直闪烁,直到完成为止,是否仍要停止此操作?

    3 回复  |  直到 13 年前
        1
  •  4
  •   Community CDub    7 年前

    答案与此问题的答案相同:

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

    (为方便起见,复印了答案:原文来源: https://stackoverflow.com/users/36860/ng5000 )

    在我之前的工作中,我们一直在努力让我们的富用户界面应用程序能够立即流畅地进行绘制。我们使用的是标准.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 u的setredraw,例如

    C# Jitter

    Suspending Layouts

        2
  •  2
  •   dotnetNinja    15 年前

    可能希望用表单的suspendlayout和resumelayout属性包围代码

    this.suspendlayout();

    //创建控件

    这一点。恢复时间(真的);

        3
  •  2
  •   ceztko Jeff Davis    13 年前

    以下是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();
        }
    }