如何将两个表单锁定在一起并将它们作为一个单独的表单移动?
How to lock two forms together and moving them as a single one?
我在 运行 时间创建了一个表单,并向其中添加了一个控件。我选择使用 New Point(Form1.Location.X + Form1.Width, Form1.Location.Y)
将 form2 定位在靠近 form1 的位置,并且两种表单边框样式都设置为“None”,因此我使用了 3 个鼠标事件以使它们“可拖动”(在 form1 和 form2 中)。我正在使用来自
的好代码
一切正常。所以当 form2 打开时问题就开始了。
我创建了一个 gif Imgur gif 以便更好地解释。
Form 1 单独 id 可移动,form2 单独 id 可移动。
Form2 移动 form1 而本身不移动。
我在 form1(usercontrol1) 中使用的代码调用 form2(qrcode):
Dim qrForm = New SchermataCode()
qrForm.ShowForm()
Form1.TopMost = True
qrform.dispose()
我在 control2(qrcode) 中使用的内容:
Private Sub qrcode_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
startPosition = e.Location
End If
End Sub
Private Sub qrcode_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button = MouseButtons.Left Then
Form1.Location = New Point(
Form1.Left + (e.X - startPosition.X),
Form1.Top + (e.Y - startPosition.Y))
End If
End Sub
Private Sub PictureBox10_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox10.MouseMove
If e.Button = MouseButtons.Left Then
Form1.Location = New Point(
Form1.Left + (e.X - startPosition.X),
Form1.Top + (e.Y - startPosition.Y))
End If
End Sub
Private Sub PictureBox10_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox10.MouseDown
If e.Button = MouseButtons.Left Then
startPosition = e.Location
End If
End Sub
这就是我生成新表单并添加 control2(二维码)的方式
Option Strict On
Public Class SchermataCode
Implements IDisposable
Private qrForm As Form = Nothing
Private qr As qrcode = Nothing
Private startPosition As Point = Point.Empty
' Dim qrcode As New qrcode
Public Sub New()
qrForm = New Form() With {
.FormBorderStyle = FormBorderStyle.None,
.StartPosition = FormStartPosition.Manual,
.Location = New Point(Form1.Location.X + Form1.Width, Form1.Location.Y),
.AutoScaleMode = AutoScaleMode.None,
.Icon = DirectCast(My.Resources.ResourceManager.GetObject("_" & My.Settings.icona), Icon),
.Dock = DockStyle.Fill,
.TopMost = True
}
qr = New qrcode()
AddHandler qr.MouseDown, AddressOf qrCode_MouseDown
AddHandler qr.MouseMove, AddressOf qrCode_MouseMove
AddHandler qr.DoubleClick, AddressOf qrCode_OnDoubleClick
qrForm.Controls.Add(qr)
End Sub
Public Function ShowForm() As Image
qrForm.ClientSize = qr.Size
qrForm.Showdialog
Form1.TopMost = True
End Function
Private Sub qrCode_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
startPosition = e.Location
End If
End Sub
Private Sub qrCode_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
qrForm.Location = New Point(
qrForm.Left + (e.X - startPosition.X),
qrForm.Top + (e.Y - startPosition.Y))
End If
End Sub
Private Sub qrCode_OnDoubleClick(ByVal sender As Object, ByVal e As EventArgs)
qrForm.Close()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If disposing Then
If qrForm IsNot Nothing Then
RemoveHandler qr.DoubleClick, AddressOf qrCode_OnDoubleClick
RemoveHandler qr.MouseDown, AddressOf qrCode_MouseDown
RemoveHandler qr.MouseMove, AddressOf qrCode_MouseMove
End If
qr?.Dispose()
qrForm?.Dispose()
End If
End Sub
End Class
有人知道吗?我想打开靠近 form1 的 form2,将两者拖在一起,如果双击 form2,则关闭它,只打开 form1。 Form1 在一起时不拖 form2。
谢谢
对于阅读这篇文章的任何人 question/answer,很多都是通过 CHAT 完成的,这不是最终的解决方案。
So my question is: I can't declare again "Dim qrForm = New
SchermataCode()" in form1(usercontrol)Mouse_move as I'm already
calling it In a button , so how can I make it public ? I tried to
insert that under Public Class UserControl1 but it goes on
Whosebug.. Thanks
这是涉及 Scope 的设计问题。
将“qrForm”的声明移动到 UserControl 级别,因此它不在 Button 处理程序中:
' ... code in UserControl (that is housed by the Main Form) ...
Private qrForm As SchermataCode
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If IsNothing(qrForm) Then
qrForm = New SchermataCode()
End If
qrForm.ShowForm()
Form1.TopMost = True
End Sub
并不是说我正在检查“qrForm”是否为空(null)或者它在创建之前是否已被处理(关闭)。
在您要移动辅助表单的处理程序中,您需要在尝试使用它之前执行类似的操作:
' ... code in UserControl (that is housed by the Main Form) ...
' The Foo() below could be any handler (like a MouseMove)
Private Sub Foo()
If (Not IsNothing(qrForm)) AndAlso (Not qrForm.IsDisposed) Then
' ... do something with "qrForm" in here (like move it) ...
End If
End Sub
-----看完评论下方发的GIF-----
天哪……我明白现在发生了什么。 您的变量名还有很多不足之处。 在 UserControl1 中,您有一个类型为 SchermataCode
的名为 qrForm
的变量。然后,在 class SchermataCode
中,您有另一个名为 qrForm
的变量,它是您要操作的实际形式!我们很接近!
首先,在classSchermataCode
中,将qrForm
的声明从Private
改为Public
:
Public Class SchermataCode
Implements IDisposable
Public qrForm As Form = Nothing
' ... the rest of the existing code ...
End Class
现在,在 UserControl1
中,我们想要访问上面的“内部”qrForm
。这看起来很奇怪,因为您将变量命名为相同的名称:
' ... inside the PictureBox5_MouseMove() method of UserControl1 ...
If Not IsNothing(qrForm) Then
' Let's make a variable that points directly to the secondary Form:
Dim frm As Form = qrForm.qrForm ' <--- use better names next time! =)
' Now let's move it:
frm.Location = New Point(
frm.Left + (e.X - startPosition.X),
frm.Top + (e.Y - startPosition.Y))
End If
希望现在问题已经解决了。
我在 运行 时间创建了一个表单,并向其中添加了一个控件。我选择使用 New Point(Form1.Location.X + Form1.Width, Form1.Location.Y)
将 form2 定位在靠近 form1 的位置,并且两种表单边框样式都设置为“None”,因此我使用了 3 个鼠标事件以使它们“可拖动”(在 form1 和 form2 中)。我正在使用来自
一切正常。所以当 form2 打开时问题就开始了。 我创建了一个 gif Imgur gif 以便更好地解释。 Form 1 单独 id 可移动,form2 单独 id 可移动。 Form2 移动 form1 而本身不移动。 我在 form1(usercontrol1) 中使用的代码调用 form2(qrcode):
Dim qrForm = New SchermataCode()
qrForm.ShowForm()
Form1.TopMost = True
qrform.dispose()
我在 control2(qrcode) 中使用的内容:
Private Sub qrcode_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
startPosition = e.Location
End If
End Sub
Private Sub qrcode_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button = MouseButtons.Left Then
Form1.Location = New Point(
Form1.Left + (e.X - startPosition.X),
Form1.Top + (e.Y - startPosition.Y))
End If
End Sub
Private Sub PictureBox10_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox10.MouseMove
If e.Button = MouseButtons.Left Then
Form1.Location = New Point(
Form1.Left + (e.X - startPosition.X),
Form1.Top + (e.Y - startPosition.Y))
End If
End Sub
Private Sub PictureBox10_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox10.MouseDown
If e.Button = MouseButtons.Left Then
startPosition = e.Location
End If
End Sub
这就是我生成新表单并添加 control2(二维码)的方式
Option Strict On
Public Class SchermataCode
Implements IDisposable
Private qrForm As Form = Nothing
Private qr As qrcode = Nothing
Private startPosition As Point = Point.Empty
' Dim qrcode As New qrcode
Public Sub New()
qrForm = New Form() With {
.FormBorderStyle = FormBorderStyle.None,
.StartPosition = FormStartPosition.Manual,
.Location = New Point(Form1.Location.X + Form1.Width, Form1.Location.Y),
.AutoScaleMode = AutoScaleMode.None,
.Icon = DirectCast(My.Resources.ResourceManager.GetObject("_" & My.Settings.icona), Icon),
.Dock = DockStyle.Fill,
.TopMost = True
}
qr = New qrcode()
AddHandler qr.MouseDown, AddressOf qrCode_MouseDown
AddHandler qr.MouseMove, AddressOf qrCode_MouseMove
AddHandler qr.DoubleClick, AddressOf qrCode_OnDoubleClick
qrForm.Controls.Add(qr)
End Sub
Public Function ShowForm() As Image
qrForm.ClientSize = qr.Size
qrForm.Showdialog
Form1.TopMost = True
End Function
Private Sub qrCode_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
startPosition = e.Location
End If
End Sub
Private Sub qrCode_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
qrForm.Location = New Point(
qrForm.Left + (e.X - startPosition.X),
qrForm.Top + (e.Y - startPosition.Y))
End If
End Sub
Private Sub qrCode_OnDoubleClick(ByVal sender As Object, ByVal e As EventArgs)
qrForm.Close()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If disposing Then
If qrForm IsNot Nothing Then
RemoveHandler qr.DoubleClick, AddressOf qrCode_OnDoubleClick
RemoveHandler qr.MouseDown, AddressOf qrCode_MouseDown
RemoveHandler qr.MouseMove, AddressOf qrCode_MouseMove
End If
qr?.Dispose()
qrForm?.Dispose()
End If
End Sub
End Class
有人知道吗?我想打开靠近 form1 的 form2,将两者拖在一起,如果双击 form2,则关闭它,只打开 form1。 Form1 在一起时不拖 form2。
谢谢
对于阅读这篇文章的任何人 question/answer,很多都是通过 CHAT 完成的,这不是最终的解决方案。
So my question is: I can't declare again "Dim qrForm = New SchermataCode()" in form1(usercontrol)Mouse_move as I'm already calling it In a button , so how can I make it public ? I tried to insert that under Public Class UserControl1 but it goes on Whosebug.. Thanks
这是涉及 Scope 的设计问题。
将“qrForm”的声明移动到 UserControl 级别,因此它不在 Button 处理程序中:
' ... code in UserControl (that is housed by the Main Form) ...
Private qrForm As SchermataCode
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If IsNothing(qrForm) Then
qrForm = New SchermataCode()
End If
qrForm.ShowForm()
Form1.TopMost = True
End Sub
并不是说我正在检查“qrForm”是否为空(null)或者它在创建之前是否已被处理(关闭)。
在您要移动辅助表单的处理程序中,您需要在尝试使用它之前执行类似的操作:
' ... code in UserControl (that is housed by the Main Form) ...
' The Foo() below could be any handler (like a MouseMove)
Private Sub Foo()
If (Not IsNothing(qrForm)) AndAlso (Not qrForm.IsDisposed) Then
' ... do something with "qrForm" in here (like move it) ...
End If
End Sub
-----看完评论下方发的GIF-----
天哪……我明白现在发生了什么。 您的变量名还有很多不足之处。 在 UserControl1 中,您有一个类型为 SchermataCode
的名为 qrForm
的变量。然后,在 class SchermataCode
中,您有另一个名为 qrForm
的变量,它是您要操作的实际形式!我们很接近!
首先,在classSchermataCode
中,将qrForm
的声明从Private
改为Public
:
Public Class SchermataCode
Implements IDisposable
Public qrForm As Form = Nothing
' ... the rest of the existing code ...
End Class
现在,在 UserControl1
中,我们想要访问上面的“内部”qrForm
。这看起来很奇怪,因为您将变量命名为相同的名称:
' ... inside the PictureBox5_MouseMove() method of UserControl1 ...
If Not IsNothing(qrForm) Then
' Let's make a variable that points directly to the secondary Form:
Dim frm As Form = qrForm.qrForm ' <--- use better names next time! =)
' Now let's move it:
frm.Location = New Point(
frm.Left + (e.X - startPosition.X),
frm.Top + (e.Y - startPosition.Y))
End If
希望现在问题已经解决了。