原文: http://zetcode.com/gui/vbwinforms/dragdrop/

Mono Visual Basic Winforms 教程的这一部分将专门用于拖放操作。

在计算机图形用户界面中,拖放是单击虚拟对象并将其拖动到其他位置或另一个虚拟对象上的动作(或支持以下动作)。 通常,它可用于调用多种动作,或在两个抽象对象之间创建各种类型的关联。 (维基百科)

拖放功能是图形用户界面最明显的方面之一。 拖放操作使您可以直观地完成复杂的事情。

拖动按钮

在第一个示例中,我们将在按钮控件上执行拖放操作。 该示例在拖放&放置协议之外执行作业。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' In this program we drag & drop
  4. ' a button control
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Public Class WinVBApp
  12. Inherits Form
  13. Private isDragging As Boolean = False
  14. Private oldX As Integer
  15. Private oldY As Integer
  16. Private button As Button
  17. Public Sub New
  18. Me.Text = "Drag & Drop button"
  19. Me.Size = New Size(270, 180)
  20. Me.InitUI
  21. Me.CenterToScreen
  22. End Sub
  23. Private Sub InitUI
  24. button = New Button
  25. button.Parent = Me
  26. button.Cursor = Cursors.Hand
  27. button.Text = "Button"
  28. button.Location = New Point(20, 20)
  29. AddHandler button.MouseDown, AddressOf Me.OnMouseDown
  30. AddHandler button.MouseUp, AddressOf Me.OnMouseUp
  31. AddHandler button.MouseMove, AddressOf Me.OnMouseMove
  32. End Sub
  33. Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
  34. isDragging = True
  35. oldX = e.X
  36. oldY = e.Y
  37. End Sub
  38. Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
  39. If isDragging
  40. button.Top = button.Top + (e.Y - oldY)
  41. button.Left = button.Left + (e.X - oldX)
  42. End If
  43. End Sub
  44. Private Sub OnMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
  45. isDragging = False
  46. End Sub
  47. Public Shared Sub Main
  48. Application.Run(New WinVBApp)
  49. End Sub
  50. End Class

该代码示例将一个常规按钮控件放在表单容器上。 通过单击按钮表面并同时用鼠标拖动它,我们可以重新放置按钮。

我们的示例中有一些支持变量。 isDragging变量告诉我们是否正在拖动对象。 oldXoldY变量在拖动过程开始之前存储 x,y 坐标。

  1. AddHandler button.MouseDown, AddressOf Me.OnMouseDown
  2. AddHandler button.MouseUp, AddressOf Me.OnMouseUp
  3. AddHandler button.MouseMove, AddressOf Me.OnMouseMove

我们为按钮插入了三种不同的鼠标处理器。 它们实现了拖放过程的三个不同阶段。 当我们单击按钮时,过程开始。 这由OnMouseDown方法处理。 第二部分是机芯。 这是当我们将对象移动到新位置时。 它以OnMouseMove方法处理。 最后一部分是过程停止的时间。 当我们释放鼠标按钮时会发生这种情况。 适当的任务委托给OnMouseUp方法。

  1. Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
  2. isDragging = True
  3. oldX = e.X
  4. oldY = e.Y
  5. End Sub

OnMouseDown方法实现了过程的第一部分。 它设置了三个必要的变量。

  1. Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
  2. If isDragging
  3. button.Top = button.Top + (e.Y - oldY)
  4. button.Left = button.Left + (e.X - oldX)
  5. End If
  6. End Sub

OnMouseMove方法中,我们重新定位按钮。 我们计算存储的 x,y 坐标与鼠标指针的新坐标之间的差。 差异将添加到按钮的TopLeft属性中,从而将其移动到新位置。

拖放 - 图1

图:拖动按钮

拖动文字

在前面的示例中,我们确实拖动了控件上的&拖放。 接下来,我们将对文本数据进行拖放操作。 在这里,我们将使用 Winforms 库提供的拖放协议。

拖放操作是 Winforms 中的标准通信协议。 我们有两个基本对象。 drag sourcedrop target

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' In this program we drag & drop
  4. ' text
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Public Class WinVBApp
  12. Inherits Form
  13. Private txtBox As TextBox
  14. Private btn As Button
  15. Public Sub New
  16. Me.Text = "Drag & Drop text"
  17. Me.Size = New Size(250, 200)
  18. Me.InitUI
  19. Me.CenterToScreen
  20. End Sub
  21. Private Sub InitUI
  22. btn = New Button
  23. txtBox = New TextBox
  24. Me.SuspendLayout
  25. btn.AllowDrop = True
  26. btn.Location = New Point(150, 50)
  27. txtBox.Location = New Point(15, 50)
  28. Me.Controls.Add(btn)
  29. Me.Controls.Add(txtBox)
  30. Me.ResumeLayout
  31. AddHandler btn.DragEnter, AddressOf Me.OnDragEnter
  32. AddHandler btn.DragDrop, AddressOf Me.OnDragDrop
  33. AddHandler txtBox.MouseDown, AddressOf Me.OnMouseDown
  34. End Sub
  35. Private Sub OnDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
  36. e.Effect = DragDropEffects.Copy
  37. End Sub
  38. Private Sub OnDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
  39. sender.Text = e.Data.GetData(DataFormats.Text)
  40. End Sub
  41. Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
  42. sender.DoDragDrop(sender.Text, DragDropEffects.Copy)
  43. End Sub
  44. Public Shared Sub Main
  45. Application.Run(New WinVBApp)
  46. End Sub
  47. End Class

我们在表单上有两个控件。 一个按钮和一个文本框。 我们将文本从文本框中拖放到按钮上。

  1. btn.AllowDrop = True

我们将AllowDrop属性设置为true。 默认情况下不启用删除。

  1. AddHandler btn.DragEnter, AddressOf Me.OnDragEnter
  2. AddHandler btn.DragDrop, AddressOf Me.OnDragDrop
  3. AddHandler txtBox.MouseDown, AddressOf Me.OnMouseDown

同样,拖放过程分为三个步骤。 对于每个特定步骤,我们有三种方法。

  1. Private Sub OnDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
  2. e.Effect = DragDropEffects.Copy
  3. End Sub

当鼠标指针进入放置目标控件的区域时,将启动DragEnter事件。 必须设置Effect属性。 拖动源和放置目标的DragDropEffects必须相等。 否则,该操作将无法进行。

  1. Private Sub OnDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
  2. sender.Text = e.Data.GetData(DataFormats.Text)
  3. End Sub

最后,我们有OnDragDrop方法。 在这里,我们从事件对象获取数据并将其设置为按钮Text属性。

  1. Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
  2. sender.DoDragDrop(sender.Text, DragDropEffects.Copy)
  3. End Sub

OnMouseDown方法中,我们初始化了拖放过程。 我们使用DoDragDrop方法启动该过程。 DragDropEffects.Copy参数指定操作的类型。 实质上,我们可以在拖放操作期间复制文本或移动文本。

拖放 - 图2

图:文本拖放

拖动图像

在最后一个示例中,我们将&拖放图像拖到窗体上。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' In this program we drag & drop
  4. ' an image
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Public Class WinVBApp
  12. Inherits Form
  13. Private IsDragging As Boolean = False
  14. Private oldX As Integer
  15. Private oldY As Integer
  16. Private dropRect As Rectangle
  17. Private picBox As PictureBox
  18. Private image As Bitmap
  19. Private brsh As Brush
  20. Public Sub New
  21. Me.Text = "Drag & Drop image"
  22. Me.Size = New Size(350, 250)
  23. Me.InitUI
  24. Me.CenterToScreen
  25. End Sub
  26. Private Sub InitUI
  27. isDragging = False
  28. dropRect = New Rectangle(10, 10, 200, 160)
  29. brsh = Brushes.Gray
  30. picBox = New PictureBox
  31. Me.LoadImage
  32. picBox.Parent = Me
  33. picBox.Location = New Point(100, 50)
  34. picBox.Size = New Size(image.Width, image.Height)
  35. picBox.Image = image
  36. picBox.Cursor = Cursors.Hand
  37. AddHandler Me.Paint, AddressOf Me.OnPaint
  38. AddHandler picBox.MouseDown, AddressOf Me.OnMouseDown
  39. AddHandler picBox.MouseMove, AddressOf Me.OnMouseMove
  40. AddHandler picBox.MouseUp, AddressOf Me.OnMouseUp
  41. End Sub
  42. Private Sub LoadImage
  43. Try
  44. image = New Bitmap("image.jpg")
  45. Catch
  46. Console.WriteLine("Error reading image")
  47. Environment.Exit(1)
  48. End Try
  49. End Sub
  50. Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
  51. isDragging = True
  52. oldX = e.X
  53. oldY = e.Y
  54. End Sub
  55. Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
  56. If isDragging
  57. picBox.Top = picBox.Top + (e.Y - oldY)
  58. picBox.Left = picBox.Left + (e.X - oldX)
  59. End If
  60. End Sub
  61. Private Sub OnMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
  62. isDragging = False
  63. If dropRect.Contains(picBox.Bounds)
  64. brsh = Brushes.Gold
  65. Else
  66. brsh = Brushes.Gray
  67. End If
  68. Me.Refresh
  69. End Sub
  70. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  71. Dim g As Graphics = e.Graphics
  72. g.FillRectangle(brsh, dropRect)
  73. End Sub
  74. Public Shared Sub Main
  75. Application.Run(New WinVBApp)
  76. End Sub
  77. End Class

在我们的示例中,我们有一个PictureBox,并绘制了一个灰色矩形。 如果将图片放在矩形内,则矩形的颜色变为金色。

  1. brsh = Brushes.Gray

brsh变量保存矩形的笔刷。 默认情况下为灰色。

  1. Private Sub LoadImage
  2. Try
  3. image = New Bitmap("image.jpg")
  4. Catch
  5. Console.WriteLine("Error reading image")
  6. Environment.Exit(1)
  7. End Try
  8. End Sub

LoadImage方法为PictureBox控件加载位图。

  1. If dropRect.Contains(picBox.Bounds)
  2. brsh = Brushes.Gold
  3. Else
  4. brsh = Brushes.Gray
  5. End If

OnMouseUp方法中,我们确定矩形的笔刷。 如果图片框的边界在矩形内,则画笔为金色;否则,画笔为金色。 否则为灰色。

  1. Me.Refresh

我们必须调用Refresh方法来激活新的画笔颜色。

拖放 - 图3

图:拖放图像

本章致力于使用带有 Visual Basic 语言的 Mono Winforms 库拖放操作。