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

前端 未结 10 1954
小鲜肉
小鲜肉 2020-11-22 01:34

I have a control which I have to make large modifications to. I\'d like to completely prevent it from redrawing while I do that - SuspendLayout and ResumeLayout aren\'t eno

10条回答
  •  攒了一身酷
    2020-11-22 01:44

    At my previous job we struggled with getting our rich UI app to paint instantly and smoothly. We were using standard .Net controls, custom controls and devexpress controls.

    After a lot of googling and reflector usage I came across the WM_SETREDRAW win32 message. This really stops controls drawing whilst you update them and can be applied, IIRC to the parent/containing panel.

    This is a very very simple class demonstrating how to use this message:

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

    There are fuller discussions on this - google for C# and WM_SETREDRAW, e.g.

    C# Jitter

    Suspending Layouts

    And to whom it may concern, this is similar example in VB:

    Public Module Extensions
        
        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
        
        Public Sub ResumeDrawing(ByVal Target As Control, ByVal Redraw As Boolean)
            SendMessage(Target.Handle, WM_SETREDRAW, True, 0)
            If Redraw Then
                Target.Refresh()
            End If
        End Sub
    
        
        Public Sub SuspendDrawing(ByVal Target As Control)
            SendMessage(Target.Handle, WM_SETREDRAW, False, 0)
        End Sub
    
        
        Public Sub ResumeDrawing(ByVal Target As Control)
            ResumeDrawing(Target, True)
        End Sub
    End Module
    

提交回复
热议问题