Оптимизация управления изменением размера - PullRequest
2 голосов
/ 17 мая 2011

У меня есть пользовательский UserControl, у которого есть StatusStrip. Поэтому я изменяю размер этого элемента управления, когда пользователь перетаскивает угол этой полосы состояния. Однако изменение размера не очень хорошее: во время изменения размера на родительском элементе управления могут наблюдаться временные белые области, и иногда, если изменение размера слишком быстрое, пользователь «теряет» элемент управления (который останавливает изменение размера).

enter image description here

Option Infer On

Public Class FloattingGrid
  Inherits System.Windows.Forms.UserControl

  Dim mouseDownLocation As Nullable(Of Point)

  Private Sub StatusStrip1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles StatusStrip1.MouseMove

    If mouseDownLocation.HasValue Then
      Dim newPosition = Cursor.Position
      Dim dx = newPosition.X - mouseDownLocation.Value.X
      Dim dy = newPosition.Y - mouseDownLocation.Value.Y
      'Dim oldRect = New Rectangle(Me.Location, Me.Size)'
      Me.Size = New Size(Me.Width + dx, Me.Height + dy)
      mouseDownLocation = newPosition

      If Me.Parent IsNot Nothing Then
        'Me.Parent.Invalidate(oldRect) '
        Me.Parent.Refresh()
      End If
    Else

      If e.X > Me.Width - 20 Then
        If Cursor <> Cursors.SizeNWSE Then Cursor = Cursors.SizeNWSE
      Else
        If Cursor = Cursors.SizeNWSE Then Cursor = Cursors.Default
      End If
    End If
  End Sub

  Private Sub StatusStrip1_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusStrip1.MouseLeave
    Cursor = Cursors.Default
    mouseDownLocation = Nothing
    'Me.ResumeLayout() '
  End Sub

  Private Sub StatusStrip1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles StatusStrip1.MouseDown
    If Cursor = Cursors.SizeNWSE Then
      'Me.SuspendLayout() '
      mouseDownLocation = Cursor.Position
    End If
  End Sub

  Private Sub StatusStrip1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles StatusStrip1.MouseUp
    mouseDownLocation = Nothing
    'Me.ResumeLayout()'
  End Sub

  ' Private Sub FloattingGrid_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove '    
  ' End Sub '

  Private Sub FloattingGrid_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.ResizeRedraw = True
  End Sub
End Class

Я думаю, что такое поведение может быть вызвано недействительностью родителей. Есть ли способ просто BeginInvalidate и не ждать, пока родитель не сделает недействительным весь регион?

1 Ответ

1 голос
/ 17 мая 2011

BeginInvoke не имеет ничего общего с рисованием и не имеет никакого отношения к реализации задержки. Это все о многопоточном доступе, который вы здесь не делаете. Это не правильное решение.

И нет ничего плохого в том, чтобы звонить Invalidate. Это просто помечает область как требующую покраски. На самом деле это не приводит к перекрашиванию этой области несколько раз. Если область, которую вы объявили недействительной, уже была признана недействительной, то это запрет, поэтому здесь не нужно ничего замедлять. Если вы хотите, чтобы он был перекрашен немедленно , вам нужно будет вызвать что-то вроде Refresh.

Одна вещь, которую вы могли бы сделать, - предотвратить родительский элемент управления от попытки изменить его размер и изменить расположение дочерних элементов управления, чтобы приспособить новую позицию StatusStrip. Для этого вызовите метод SuspendLayout , когда вы начнете изменять размер, и метод ResumeLayout , когда вы закончите.

Конечно, это не гарантирует решения вашей проблемы. Вы по-прежнему очень вероятно, что увидите лаги, а в областях, которые еще не были окрашены, появляются белые или черные области. Это происходит в других приложениях и даже при изменении размеров окон. Единственное решение этой проблемы - двойная буферизация, отрисовка всего во временный фоновый буфер и затем отрисовка всего законченного изображения на экран.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...