一尘不染

如何为控件及其子控件暂停绘画?

c#

我有一个控件,我必须对其进行较大的修改。我想完全避免重绘,而SuspendLayout和ResumeLayout不够。如何为控件及其子控件暂停绘画?


阅读 319

收藏
2020-05-19

共1个答案

一尘不染

在我之前的工作中,我们一直在努力获取丰富的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, 0)
        If Redraw Then
            Target.Refresh()
        End If
    End Sub

    <Extension()>
    Public Sub SuspendDrawing(ByVal Target As Control)
        SendMessage(Target.Handle, WM_SETREDRAW, False, 0)
    End Sub

    <Extension()>
    Public Sub ResumeDrawing(ByVal Target As Control)
        ResumeDrawing(Target, True)
    End Sub
End Module
2020-05-19