我有一个控件,我必须对其进行大量修改。我想在我这样做时完全防止它重绘 - SuspendLayout 和 ResumeLayout 是不够的。如何暂停控件及其子控件的绘制?
在我之前的工作中,我们努力让我们丰富的 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# 抖动
暂停布局
对于它可能关心的人来说,这是 VB 中的一个类似示例:
Public Module Extensions <DllImport("user32.dll")> Private Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Boolean, ByVal lParam As IntPtr) As Integer End Function Private Const WM_SETREDRAW As Integer = 11 ' Extension methods for Control <Extension()> Public Sub ResumeDrawing(ByVal Target As Control, ByVal Redraw As Boolean) SendMessage(Target.Handle, WM_SETREDRAW, True, IntPtr.Zero) If Redraw Then Target.Refresh() End If End Sub <Extension()> Public Sub SuspendDrawing(ByVal Target As Control) SendMessage(Target.Handle, WM_SETREDRAW, False, IntPtr.Zero) End Sub <Extension()> Public Sub ResumeDrawing(ByVal Target As Control) ResumeDrawing(Target, True) End Sub End Module