在 运行 时间创建一个新表单并添加事件处理程序
Create a new Form and add event handlers at Run Time
我正在尝试在 Run-Time 创建一个新的 border-less 表单,事件处理程序需要移动没有标题的表单。
表单是一个对话框,可以使用专门的控件显示呈现的二维码。
表单还应自行调整大小以适应不同大小的二维码。
这是我到目前为止写的:
Imports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Dim schermataqrcode As New Form
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
schermataqrcode.FormBorderStyle = FormBorderStyle.None
AddHandler schermataqrcode.MouseDown, AddressOf schermataqrcode.MouseDown
AddHandler schermataqrcode.MouseUp, AddressOf schermataqrcode.MouseUp
AddHandler schermataqrcode.MouseMove, AddressOf schermataqrcode.MouseMove
Dim qrcode As New qrcode
qrcode.Dock = DockStyle.Fill
schermataqrcode.Controls.Add(qrcode)
schermataqrcode.StartPosition = FormStartPosition.CenterScreen
schermataqrcode.Show()
End Sub
Public Class schermatacode
Private IsDraggingForm As Boolean = False
Private MousePos As New System.Drawing.Point(0, 0)
Private Sub schermataqrcode_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
IsDraggingForm = True
MousePos = e.Location
End If
End Sub
Private Sub schermataqrcode_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then IsDraggingForm = False
End Sub
Private Sub schermataqrcode_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If IsDraggingForm Then
Dim temp As Point = New Point(Me.Location + (e.Location - MousePos))
Me.Location = temp
temp = Nothing
End If
End Sub
End Class
End Class
我不确定,因为 VS 错误:
BC30577 'AddressOf' operand must be the name of a method (without parentheses).
BC30577 'AddressOf' operand must be the name of a method (without parentheses).
BC30577 'AddressOf' operand must be the name of a method (without parentheses).
BC30456 'Location' is not a member of 'Form1.schermatacode'.
BC30456 'Location' is not a member of 'Form1.schermatacode'.
当前代码中的问题:
选项严格是 Off
schermataqrcode
表单的事件应该由 schermatacode
class 对象处理,但赋值不指向 schermatacode
class 全部:
AddHandler schermataqrcode.MouseDown, AddressOf schermataqrcode.MouseDown
' should be:
AddHandler schermataqrcode.MouseDown, AddressOf schermatacode.schermataqrcode_MouseDown
但您没有创建此 class 的实例(它不是静态的,也不可能是静态的)并且在任何情况下都声明了事件处理程序 Private
,因此无论如何您都无法访问它们。
即使事件处理程序设置正确,Form 的 ClientArea 也会完全被停靠的 Control 填充,因此它不会接收鼠标事件。
这个:Dim temp As Point = New Point(Me.Location + (e.Location - MousePos))
不能用:
- Me
不是表单,它是 schermatacode
class,它没有 Location
属性.
- Option Strict Off
向您隐藏了 Me.Location + (e.Location - MousePos)
不是 return 可用的点数。当你设置 Option Strict On
.
时,看看 Point = Point + (Point - Point)
实际上是什么
这里有一些你可以做的事情:
移动 SchermataCode class 对象中的所有逻辑:您只是创建一个包含单个控件的标准表单(根据描述,但您可以添加所有控件你要)。 class 处理表单和 QR 控件的创建,还设置所有需要的事件处理程序。
对所有内容使用单个 class 对象,您只需初始化 class 并在需要时使用它,例如 Dim qrForm = New SchermataCode()
。
SchermataCode
对象然后可以公开 public 方法和属性,允许使用其功能,只需调用方法或检查 属性,就像通常发生的那样与 .Net classes.
在示例代码中,SchermataCode
公开了一个 ShowForm()
public 方法,该方法将窗体显示为对话框。您可以将要呈现为 QR 图像的字符串传递给此方法。这样,您可以使用同一个 class 来显示多个表单,也可以在应用程序的整个生命周期中使用同一个 class 对象。
► 重要的是要注意 SchermataCode
还公开了一个 Dispose()
方法:此方法允许处理表单、QR 控件并删除添加到这些控件的所有处理程序。当您不再需要 SchermataCode
时,调用此方法非常重要 - 就像在 .Net 中一样 - 释放这些对象正在分配的资源。
当然,如果需要,您可以在之后创建另一个实例。
► 注意: 由于二维码控件占据了表单的整个客户区,border-less 表单移动由二维码控件处理,使用其MouseDown
和 MouseMove
事件而不是表单的事件(因为表单不会接收鼠标事件)。
我不确定 QR 控件是否具有与这些事件相关的某些特定功能(如果您单击它,就会发生一些事情。如果是这样的话请告诉我)。
此外,双击 QR 控件会导致表单关闭。
例如,创建一个SchermataCode
实例并按顺序显示两个Form,在一种情况下将ShowForm()
return的图像分配给局部变量并分配给PictureBox控件在另一个(我不确定 QR 控件 return 是否是渲染图像,或者即使你需要它,它也是为了展示这个 class 是如何工作的)。
Dim qrForm = New SchermataCode()
' Shown the Dialog using the default Size
Dim result As Image = qrForm.ShowForm("<Some QR String>")
qrForm.QRImageSize = New Size(200, 200)
PictureBox1.Image = qrForm.ShowForm("<Some Other QR String>")
qrForm.Dispose()
QRImageSize
public 属性 允许在显示新对话框之前更改 QR 控件的大小。默认大小为 (500, 500)
.
修改 SchermataCode
class:
Public Class SchermataCode
Implements IDisposable
Private qrForm As Form = Nothing
Private qr As qrcode = Nothing
Private startPosition As Point = Point.Empty
Public Sub New()
qrForm = New Form() With {
.FormBorderStyle = FormBorderStyle.None,
.StartPosition = FormStartPosition.CenterScreen
}
qr = New qrcode() With {.Size = QRImageSize}
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 Property QRImageSize As Size = New Size(500, 500)
Public Function ShowForm(qrString As String) As Image
If QRImageSize <> qr.Size Then qr.Size = QRImageSize
qrForm.ClientSize = qr.Size
qr.Text = qrString
qrForm.ShowDialog()
Return qr.Image
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 qr IsNot Nothing Then
RemoveHandler qr.MouseDown, AddressOf qrCode_MouseDown
RemoveHandler qr.MouseMove, AddressOf qrCode_MouseMove
RemoveHandler qr.DoubleClick, AddressOf qrCode_OnDoubleClick
End If
qr?.Dispose()
qrForm?.Dispose()
End If
End Sub
End Class
此处使用null conditional operator以避免在处置某些对象时检查null(例如qrForm?.Dispose()
)。
如果您的 VB.Net 版本不允许,请更改它,例如:
If qrForm IsNot Nothing Then qrForm.Dispose()
我正在尝试在 Run-Time 创建一个新的 border-less 表单,事件处理程序需要移动没有标题的表单。
表单是一个对话框,可以使用专门的控件显示呈现的二维码。
表单还应自行调整大小以适应不同大小的二维码。
这是我到目前为止写的:
Imports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Dim schermataqrcode As New Form
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
schermataqrcode.FormBorderStyle = FormBorderStyle.None
AddHandler schermataqrcode.MouseDown, AddressOf schermataqrcode.MouseDown
AddHandler schermataqrcode.MouseUp, AddressOf schermataqrcode.MouseUp
AddHandler schermataqrcode.MouseMove, AddressOf schermataqrcode.MouseMove
Dim qrcode As New qrcode
qrcode.Dock = DockStyle.Fill
schermataqrcode.Controls.Add(qrcode)
schermataqrcode.StartPosition = FormStartPosition.CenterScreen
schermataqrcode.Show()
End Sub
Public Class schermatacode
Private IsDraggingForm As Boolean = False
Private MousePos As New System.Drawing.Point(0, 0)
Private Sub schermataqrcode_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
IsDraggingForm = True
MousePos = e.Location
End If
End Sub
Private Sub schermataqrcode_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left Then IsDraggingForm = False
End Sub
Private Sub schermataqrcode_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If IsDraggingForm Then
Dim temp As Point = New Point(Me.Location + (e.Location - MousePos))
Me.Location = temp
temp = Nothing
End If
End Sub
End Class
End Class
我不确定,因为 VS 错误:
BC30577 'AddressOf' operand must be the name of a method (without parentheses).
BC30577 'AddressOf' operand must be the name of a method (without parentheses).
BC30577 'AddressOf' operand must be the name of a method (without parentheses).
BC30456 'Location' is not a member of 'Form1.schermatacode'.
BC30456 'Location' is not a member of 'Form1.schermatacode'.
当前代码中的问题:
选项严格是
Off
schermataqrcode
表单的事件应该由schermatacode
class 对象处理,但赋值不指向schermatacode
class 全部:AddHandler schermataqrcode.MouseDown, AddressOf schermataqrcode.MouseDown ' should be: AddHandler schermataqrcode.MouseDown, AddressOf schermatacode.schermataqrcode_MouseDown
但您没有创建此 class 的实例(它不是静态的,也不可能是静态的)并且在任何情况下都声明了事件处理程序
Private
,因此无论如何您都无法访问它们。即使事件处理程序设置正确,Form 的 ClientArea 也会完全被停靠的 Control 填充,因此它不会接收鼠标事件。
这个:
时,看看Dim temp As Point = New Point(Me.Location + (e.Location - MousePos))
不能用: -Me
不是表单,它是schermatacode
class,它没有Location
属性.
-Option Strict Off
向您隐藏了Me.Location + (e.Location - MousePos)
不是 return 可用的点数。当你设置Option Strict On
.Point = Point + (Point - Point)
实际上是什么
这里有一些你可以做的事情:
移动 SchermataCode class 对象中的所有逻辑:您只是创建一个包含单个控件的标准表单(根据描述,但您可以添加所有控件你要)。 class 处理表单和 QR 控件的创建,还设置所有需要的事件处理程序。
对所有内容使用单个 class 对象,您只需初始化 class 并在需要时使用它,例如
Dim qrForm = New SchermataCode()
。SchermataCode
对象然后可以公开 public 方法和属性,允许使用其功能,只需调用方法或检查 属性,就像通常发生的那样与 .Net classes.
在示例代码中,SchermataCode
公开了一个ShowForm()
public 方法,该方法将窗体显示为对话框。您可以将要呈现为 QR 图像的字符串传递给此方法。这样,您可以使用同一个 class 来显示多个表单,也可以在应用程序的整个生命周期中使用同一个 class 对象。
► 重要的是要注意 SchermataCode
还公开了一个 Dispose()
方法:此方法允许处理表单、QR 控件并删除添加到这些控件的所有处理程序。当您不再需要 SchermataCode
时,调用此方法非常重要 - 就像在 .Net 中一样 - 释放这些对象正在分配的资源。
当然,如果需要,您可以在之后创建另一个实例。
► 注意: 由于二维码控件占据了表单的整个客户区,border-less 表单移动由二维码控件处理,使用其MouseDown
和 MouseMove
事件而不是表单的事件(因为表单不会接收鼠标事件)。
我不确定 QR 控件是否具有与这些事件相关的某些特定功能(如果您单击它,就会发生一些事情。如果是这样的话请告诉我)。
此外,双击 QR 控件会导致表单关闭。
例如,创建一个SchermataCode
实例并按顺序显示两个Form,在一种情况下将ShowForm()
return的图像分配给局部变量并分配给PictureBox控件在另一个(我不确定 QR 控件 return 是否是渲染图像,或者即使你需要它,它也是为了展示这个 class 是如何工作的)。
Dim qrForm = New SchermataCode()
' Shown the Dialog using the default Size
Dim result As Image = qrForm.ShowForm("<Some QR String>")
qrForm.QRImageSize = New Size(200, 200)
PictureBox1.Image = qrForm.ShowForm("<Some Other QR String>")
qrForm.Dispose()
QRImageSize
public 属性 允许在显示新对话框之前更改 QR 控件的大小。默认大小为 (500, 500)
.
修改 SchermataCode
class:
Public Class SchermataCode
Implements IDisposable
Private qrForm As Form = Nothing
Private qr As qrcode = Nothing
Private startPosition As Point = Point.Empty
Public Sub New()
qrForm = New Form() With {
.FormBorderStyle = FormBorderStyle.None,
.StartPosition = FormStartPosition.CenterScreen
}
qr = New qrcode() With {.Size = QRImageSize}
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 Property QRImageSize As Size = New Size(500, 500)
Public Function ShowForm(qrString As String) As Image
If QRImageSize <> qr.Size Then qr.Size = QRImageSize
qrForm.ClientSize = qr.Size
qr.Text = qrString
qrForm.ShowDialog()
Return qr.Image
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 qr IsNot Nothing Then
RemoveHandler qr.MouseDown, AddressOf qrCode_MouseDown
RemoveHandler qr.MouseMove, AddressOf qrCode_MouseMove
RemoveHandler qr.DoubleClick, AddressOf qrCode_OnDoubleClick
End If
qr?.Dispose()
qrForm?.Dispose()
End If
End Sub
End Class
此处使用null conditional operator以避免在处置某些对象时检查null(例如qrForm?.Dispose()
)。
如果您的 VB.Net 版本不允许,请更改它,例如:
If qrForm IsNot Nothing Then qrForm.Dispose()