在 Windows 窗体上进行拖放





4.00/5 (7投票s)
如何在运行时模式下将图像插入到窗体上,将其拖动到正确的位置,并通过数据库检索应用程序重新启动时的位置和形状

引言
这是我正在进行的一个更大项目的一部分,它是一个测试,看看拖放操作如何进行。它正如我想要的那样工作,因此我在 Code Project 上与您分享。 Code Project 是一个很棒的社区,我个人从你们其他人那里学到了很多。
你们很多人都使用过拖放功能,所以对于那些使用过的人来说,这只是另一个拖放应用程序。该应用程序的目标是学习如何在运行时模式下将图像插入到窗体上,将其拖动到正确的位置,并通过数据库检索应用程序重新启动时的位置和形状。我想指出的是,可以添加任何类型的控件,这取决于定义。 Dim MyPicturebox As New TextBox
将向窗体添加一个文本框,但您可能需要根据要添加的控件设置其他属性。
应用程序中实现了什么?
- 访问数据库的使用。(数据库位于Bin文件夹中)。
- SQL 调用以从数据库插入、更新、删除和读取数据。
- 添加处理程序以在窗体上拖放图像。
- 在窗体上以及从数据库中添加、移动和删除图像的代码。
- 工具栏控件的使用。
工作原理
我们有一个按钮来启动编辑模式。单击它时,会出现一个工具栏控件,我们就进入了编辑模式。当我们单击一个工具栏按钮时,图像会以固定位置添加到窗体。 将其添加到窗体后,您可以通过单击它并按住鼠标左键进行拖动,将其拖动到所需位置。 景观图像的存在是为了表明您可以将插入的图像放置在另一图像之上,并且还可以欣赏一些美好的事物。 最后插入的图像将始终位于最前面。
代码
加载窗体后,单击“设置为编辑模式”,工具栏将出现。 我们现在可以运行时添加图像了。
这样做的代码很简单。
Dim MyPicturebox As New PictureBox
Me.Controls.Add(MyPicturebox)
然后我们添加一些属性。
'Adding an image and properties for the image
MyPicturebox.Location = New Point(40, 40)
MyPicturebox.BringToFront()
MyPicturebox.BackgroundImageLayout = ImageLayout.Stretch
'Find out which button is pressed to insert the right image.
Dim TagId As Integer = e.ClickedItem.Tag
MyPicturebox.BackgroundImage = sender.Items.Item(TagId).Image
MyPicturebox.Name = sender.Items.Item(TagId).ToolTipText
MyPicturebox.Size = New System.Drawing.Size(40, 40)
将新图像插入到窗体后,我们希望将图像的位置和类型存储在数据库中。
' Insert position and name in the database.
selectString = "Insert into tblInfo (PosX, PosY, Name) Values (" & _
"'" & e.X & "'," & _
"'" & e.Y & "'," & _
"'" & MyPicturebox.Name & "')"
If conn.State = ConnectionState.Closed Then conn.Open()
Dim cmd = New OleDbCommand(selectString, conn)
cmd.executeNonQuery()
If conn.State = ConnectionState.Open Then conn.Close()
为了跟踪存储图像的 Id,我们必须向数据库发送一个请求,询问最后添加的图像的 Id。 Id 对于更新和删除图像很重要。 请注意,我正在使用 MyPicturebox.Tag
属性来存储图像的 Id。
'Find the corresponding Id from the database
MyPicturebox.Tag = FindLastId()
这是被调用的函数。
Private Function FindLastId() As String
selectString = "Select max(id) FROM tblInfo"
If conn.State = ConnectionState.Closed Then conn.Open()
Dim cmd = New OleDbCommand(selectString, conn)
Dim Id As String
Id = cmd.ExecuteScalar()
If conn.State = ConnectionState.Open Then conn.Close()
Return Id
End Function
在插入图像的过程中,我们必须添加一些处理程序来帮助我们进行拖放。我们添加了三个处理程序。 鼠标单击,鼠标移动和鼠标抬起,像这样。
'Add handlers that will move the image on the screen
AddHandler MyPicturebox.MouseDown, AddressOf MyMouseClick
AddHandler MyPicturebox.MouseMove, AddressOf MyMouseMove
AddHandler MyPicturebox.MouseUp, AddressOf MyMouseUp
鼠标单击处理程序
此事件正在处理两个参数。 右键单击和左键单击。 我们使用右键单击来从窗体中删除图像。 在删除图像之前,会弹出一个消息框,询问您是否要删除所选图像。
左键单击用于确定图像的位置并开始拖动。 光标更改为手形。
' The handler for the MouseClick event
Public Sub MyMouseClick(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs)
' Find out if it is in Drag and Drop mode
If ToolStrip1.Visible = True Then
'Prosedure to move an image from the workspace. Using Mousebutton right
If e.Button = Windows.Forms.MouseButtons.Right Then
Dim Response As MsgBoxResult = MsgBox(
"Do you want to remove this object",
MsgBoxStyle.YesNo, "Id = " & sender.tag)
If Response = MsgBoxResult.Yes Then ' User chose Yes.
'Remove from workspace
Me.Controls.Remove(sender)
'Remove from database
If conn.State = ConnectionState.Closed Then conn.Open()
selectString = "DELETE FROM tblInfo WHERE(Id =" & sender.Tag & ")"
cmd = New OleDbCommand(selectString, conn)
reader = cmd.ExecuteReader()
reader.Close()
If conn.State = ConnectionState.Open Then conn.Close()
End If
End If
'Procedure to select the image
If e.Button = Windows.Forms.MouseButtons.Left Then
Me.Cursor = Cursors.Hand
Dragging = True
mousex = -e.X
mousey = -e.Y
Dim clipleft As Integer = Me.PointToClient(MousePosition).X -
sender.Location.X
Dim cliptop As Integer = Me.PointToClient(MousePosition).Y -
sender.Location.Y
Dim clipwidth As Integer = Me.ClientSize.Width - (
sender.Width - clipleft)
Dim clipheight As Integer = Me.ClientSize.Height - (
sender.Height - cliptop)
Windows.Forms.Cursor.Clip = Me.RectangleToScreen(
New Rectangle(clipleft, cliptop, clipwidth, clipheight))
sender.Invalidate()
End If
End If
End Sub
鼠标移动处理程序
此处理程序根据光标的位置移动图像。 您可以看到图像跟随光标。
' The handler for the MouseMove event
Public Sub MyMouseMove(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs)
' Find out if it is in Drag and Drop mode
If RadioButton5.Checked = True Then
If Dragging Then
'move control to new position
Dim MPosition As New Point()
MPosition = Me.PointToClient(MousePosition)
MPosition.Offset(mousex, mousey)
'ensure control cannot leave container
sender.Location = MPosition
End If
End If
End Sub
鼠标抬起处理程序
这里最重要的是,我们必须将新位置存储在数据库中,为此,我们使用 SQL Update 语句。 光标更改为箭头。
' The handler for the MouseUp event
Private Sub MyMouseUp(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs)
' Find out if it is in Drag and Drop mode
If ToolStrip1.Visible = True Then
If Dragging Then
'After dragging update the database with the new position X and Y
selectString = "Update (tblInfo) Set " & _
"PosX=" & "'" & sender.Location.X & "'," & _
"PosY=" & "'" & sender.Location.Y & "'" & _
" WHERE Id=" & sender.tag & ""
If conn.State = ConnectionState.Closed Then conn.Open()
Dim cmd = New OleDbCommand(selectString, conn)
cmd.executeNonQuery()
If conn.State = ConnectionState.Open Then conn.Close()
'End the dragging
Dragging = False
Windows.Forms.Cursor.Clip = Nothing
sender.Invalidate()
End If
Me.Cursor = Cursors.Arrow
End If
End Sub
剩下要做的唯一一件事是,当我们再次启动应用程序时,我们使用 SQL 读取语句从数据库加载存储的位置和类型,并使用与前面描述的相同的技术来添加处理程序和属性。
在 Form1_Load
中,我们为所有工具栏按钮填写一个 Id。 请注意,这与图像的 Id 不同。
'Fill in an Id for the ToolStripButton
Dim i As Integer
For i = 0 To ToolStrip1.Items.Count - 1
ToolStrip1.Items.Item(i).Tag = i
Next
您可以在 Form1_Load
过程中看到所有这些。 它是经过良好注释的。
就这样。