开发者

Optimizing control resizing

I have a custom UserControl that have a StatusStrip. So, I resize this control when user drags the corner of this status strip. However, the resizing is not pretty good: temporary white areas can be observed on the parent control during the resize, and sometimes if the resizing are too fast user "loses" the control(that stops resizing).

Optimizing control resizing

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

I think that behavior could be caused by the parent's Invalidate. Is there a way to just BeginInvalidate and not wait till parent invalidates all the region?


BeginInvoke has nothing to do with painting and nothing to do with implementing a delay. It's all about cross-thread access, which you're not doing here. It's not the correct solution.

And there's nothing wrong with calling Invalidate. It just marks the area as requiring painting. It doesn't actually cause that area to get repainted multiple times. If the area you invalidate has already been invalidated, it's a no-op, so it's not responsible for slowing anything down here. If you wanted it to be repainted immediately, you would need to call something like Refresh instead.

One thing you could do is prevent the parent control from trying to resize itself and change the layout of its child controls to accommodate the new position of the StatusStrip. To do that, call the SuspendLayout method when you begin resizing and the ResumeLayout method when you finish.

Of course, that's not guaranteed to solve your problem. You're still very likely to see a lag and white or black areas appear in the regions that haven't been painted yet. This happens in other applications and even when you resize windows. The only solution to that is double-buffering, drawing everything into a temporary background buffer, and then painting that entire completed image to the screen.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜