.NET如何一次更改Control的位置和宽度?

时间:2011-07-06 16:20:48

标签: .net winforms

编辑:假设TextBox作为示例的控件 - 其中height不是问题

所以我在运行时使用鼠标来改变控件的宽度和位置(通过用鼠标抓住手柄,就像在设计时更改它一样)。但是,我注意到一些调整大小的问题,我认为可以通过调用

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

现在位置和宽度都会正确更改,但由于位置首先发生变化 - 您会看到文本框移动后模糊的宽度会发生变化。现在通过Suspend和ResumeLayout阅读,我猜他们应该在构造控件之前调用它们。在这种情况下:如何确保位置和宽度立即改变以避免模糊?

编辑:已解决 - 以下代码允许我在设置属性之前暂停绘制控件,然后继续。而不是暂停布局*

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

2 个答案:

答案 0 :(得分:1)

防止这种类型的闪烁发生的适当解决方案不会同时改变这两个值,因为一个将始终设置在另一个之前,但设置表单使用双缓冲。这样,您的更改会在复制到可见区域之前从屏幕上绘制出来。您可以在表单上找到此属性。

MSDN:有关DoubleBuffered control property

的其他信息

答案 1 :(得分:1)

而不是panel.SuspendLayout(),请this.SuspendLayout()。 Suspend和Resume保证会遍历实际的对象树,但我从来没有幸运地从容器树中流下来。