开发者

.NET How to change Control's Location and Width at once?

开发者 https://www.devze.com 2023-03-17 13:52 出处:网络
Edit: Assume a TextBox as the control for the example - where height is not an issue So I am using the mouse to change a control\'s width and location at runtime (through grabbing a handle with a mou

Edit: Assume a TextBox as the control for the example - where height is not an issue

So I am using the mouse to change a control's width and location at runtime (through grabbing a handle with a mouse, much the same way that you can change it at design time). However, I am noticing some resizing issues, which I thought would be fixed by calling

<panel>.SuspendLayout
<control>.location = new Point(x, y)
<control>.width = newWidth
<panel>.ResumeLayout

Now both the location and width change correctly, but because the location changes first - you see a blur of the textbox changing width after it moves. Now reading开发者_JAVA技巧 through Suspend and ResumeLayout, I guess they are supposed to be called before the controls are constructed. With that being the case: how do I make sure the location and width change at once to avoid the blur?

Edit: Solved - The following code allowed me to suspend drawing the control before the properties were set, then resume afterward. As opposed to suspending the layout*

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Integer, _
                                                                ByVal wMsg As Integer, _
                                                                ByVal wParam As Integer,
                                                                ByVal lParam As Integer) As Integer

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, 1, 0)
  If Redraw Then
    Target.Refresh()
  End If
End Sub

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

<Extension()>
Public Sub ResumeDrawing(ByVal Target As Control)
  ResumeDrawing(Target, True)
End Sub


Instead of panel.SuspendLayout(), do this.SuspendLayout(). Suspend and Resume are guaranteed to traverse down the actual object tree, but I've never had luck with it trickling down the container tree.


An appropriate solution to preventing this type of flickering to occur wouldn't be changing both of the values at once, as one will always be set before the other, but setting the form to use double buffering. This way, your changes are drawn off screen before being copied onto your visible region. You can find this property on your form.

MSDN: For additional information on the DoubleBuffered control property.

0

精彩评论

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