Как я приостанавливаю рисование за управление и его детей?

Аналогично, со словарями массивов можно:

var dict1 = [String:[Int]]()
var dict2 = [String:[Int]]()
dict1["key"] = [1,2,3]
dict2["key"] = [4,5,6]
dict1["key"] = dict1["key"]! + dict2["key"]!
print(dict1["key"]!)

, и вы можете перебирать dict1 и добавлять dict2, если «ключ» соответствует

179
задан Simon 28 January 2009 в 13:46
поделиться

3 ответа

В моем предыдущем задании мы боролись с тем, чтобы заставлять наше богатое приложение UI нарисовать немедленно и гладко. Мы использовали стандартные средства управления .NET, пользовательские элементы управления и средства управления devexpress.

После большого поиска с помощью Google и использования отражателя я столкнулся с сообщением 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 для 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
295
ответ дан Visual Vincent 4 November 2019 в 15:51
поделиться

Я обычно использую немного измененную версию ответа ngLink .

public class MyControl : Control
{
    private int suspendCounter = 0;

    private void SuspendDrawing()
    {
        if(suspendCounter == 0) 
            SendMessage(this.Handle, WM_SETREDRAW, false, 0);
        suspendCounter++;
    }

    private void ResumeDrawing()
    {
        suspendCounter--; 
        if(suspendCounter == 0) 
        {
            SendMessage(this.Handle, WM_SETREDRAW, true, 0);
            this.Refresh();
        }
    }
}

Это позволяет вставлять вызовы приостановки / возобновления. Убедитесь, что каждый SuspendDrawing сопоставлен с ResumeDrawing . Следовательно, публиковать их, вероятно, было бы не очень хорошей идеей.

16
ответ дан 23 November 2019 в 06:15
поделиться

Хорошее решение без использования взаимодействия:

Как всегда, просто включите DoubleBuffered = true в своем CustomControl. Затем, если у вас есть какие-либо контейнеры, такие как FlowLayoutPanel или TableLayoutPanel, создайте класс из каждого из этих типов и в конструкторах включите двойную буферизацию. Теперь просто используйте производные контейнеры вместо контейнеров Windows.Forms.

class TableLayoutPanel : System.Windows.Forms.TableLayoutPanel
{
    public TableLayoutPanel()
    {
        DoubleBuffered = true;
    }
}

class FlowLayoutPanel : System.Windows.Forms.FlowLayoutPanel
{
    public FlowLayoutPanel()
    {
        DoubleBuffered = true;
    }
}
8
ответ дан 23 November 2019 в 06:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: