Mono Visual Basic Winforms 教程的这一部分将专门用于拖放操作。
在计算机图形用户界面中,拖放是单击虚拟对象并将其拖动到其他位置或另一个虚拟对象上的动作(或支持以下动作)。 通常,它可用于调用多种动作,或在两个抽象对象之间创建各种类型的关联。 (维基百科)
拖放功能是图形用户界面最明显的方面之一。 拖放操作使您可以直观地完成复杂的事情。
拖动按钮
在第一个示例中,我们将在按钮控件上执行拖放操作。 该示例在拖放&放置协议之外执行作业。
' ZetCode Mono Visual Basic Winforms tutorial'' In this program we drag & drop' a button control'' author jan bodnar' last modified May 2009' website www.zetcode.comImports System.Windows.FormsImports System.DrawingPublic Class WinVBAppInherits FormPrivate isDragging As Boolean = FalsePrivate oldX As IntegerPrivate oldY As IntegerPrivate button As ButtonPublic Sub NewMe.Text = "Drag & Drop button"Me.Size = New Size(270, 180)Me.InitUIMe.CenterToScreenEnd SubPrivate Sub InitUIbutton = New Buttonbutton.Parent = Mebutton.Cursor = Cursors.Handbutton.Text = "Button"button.Location = New Point(20, 20)AddHandler button.MouseDown, AddressOf Me.OnMouseDownAddHandler button.MouseUp, AddressOf Me.OnMouseUpAddHandler button.MouseMove, AddressOf Me.OnMouseMoveEnd SubPrivate Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)isDragging = TrueoldX = e.XoldY = e.YEnd SubPrivate Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)If isDraggingbutton.Top = button.Top + (e.Y - oldY)button.Left = button.Left + (e.X - oldX)End IfEnd SubPrivate Sub OnMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)isDragging = FalseEnd SubPublic Shared Sub MainApplication.Run(New WinVBApp)End SubEnd Class
该代码示例将一个常规按钮控件放在表单容器上。 通过单击按钮表面并同时用鼠标拖动它,我们可以重新放置按钮。
我们的示例中有一些支持变量。 isDragging变量告诉我们是否正在拖动对象。 oldX和oldY变量在拖动过程开始之前存储 x,y 坐标。
AddHandler button.MouseDown, AddressOf Me.OnMouseDownAddHandler button.MouseUp, AddressOf Me.OnMouseUpAddHandler button.MouseMove, AddressOf Me.OnMouseMove
我们为按钮插入了三种不同的鼠标处理器。 它们实现了拖放过程的三个不同阶段。 当我们单击按钮时,过程开始。 这由OnMouseDown方法处理。 第二部分是机芯。 这是当我们将对象移动到新位置时。 它以OnMouseMove方法处理。 最后一部分是过程停止的时间。 当我们释放鼠标按钮时会发生这种情况。 适当的任务委托给OnMouseUp方法。
Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)isDragging = TrueoldX = e.XoldY = e.YEnd Sub
OnMouseDown方法实现了过程的第一部分。 它设置了三个必要的变量。
Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)If isDraggingbutton.Top = button.Top + (e.Y - oldY)button.Left = button.Left + (e.X - oldX)End IfEnd Sub
在OnMouseMove方法中,我们重新定位按钮。 我们计算存储的 x,y 坐标与鼠标指针的新坐标之间的差。 差异将添加到按钮的Top和Left属性中,从而将其移动到新位置。

图:拖动按钮
拖动文字
在前面的示例中,我们确实拖动了控件上的&拖放。 接下来,我们将对文本数据进行拖放操作。 在这里,我们将使用 Winforms 库提供的拖放协议。
拖放操作是 Winforms 中的标准通信协议。 我们有两个基本对象。 drag source和drop target。
' ZetCode Mono Visual Basic Winforms tutorial'' In this program we drag & drop' text'' author jan bodnar' last modified May 2009' website www.zetcode.comImports System.Windows.FormsImports System.DrawingPublic Class WinVBAppInherits FormPrivate txtBox As TextBoxPrivate btn As ButtonPublic Sub NewMe.Text = "Drag & Drop text"Me.Size = New Size(250, 200)Me.InitUIMe.CenterToScreenEnd SubPrivate Sub InitUIbtn = New ButtontxtBox = New TextBoxMe.SuspendLayoutbtn.AllowDrop = Truebtn.Location = New Point(150, 50)txtBox.Location = New Point(15, 50)Me.Controls.Add(btn)Me.Controls.Add(txtBox)Me.ResumeLayoutAddHandler btn.DragEnter, AddressOf Me.OnDragEnterAddHandler btn.DragDrop, AddressOf Me.OnDragDropAddHandler txtBox.MouseDown, AddressOf Me.OnMouseDownEnd SubPrivate Sub OnDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)e.Effect = DragDropEffects.CopyEnd SubPrivate Sub OnDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)sender.Text = e.Data.GetData(DataFormats.Text)End SubPrivate Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)sender.DoDragDrop(sender.Text, DragDropEffects.Copy)End SubPublic Shared Sub MainApplication.Run(New WinVBApp)End SubEnd Class
我们在表单上有两个控件。 一个按钮和一个文本框。 我们将文本从文本框中拖放到按钮上。
btn.AllowDrop = True
我们将AllowDrop属性设置为true。 默认情况下不启用删除。
AddHandler btn.DragEnter, AddressOf Me.OnDragEnterAddHandler btn.DragDrop, AddressOf Me.OnDragDropAddHandler txtBox.MouseDown, AddressOf Me.OnMouseDown
同样,拖放过程分为三个步骤。 对于每个特定步骤,我们有三种方法。
Private Sub OnDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)e.Effect = DragDropEffects.CopyEnd Sub
当鼠标指针进入放置目标控件的区域时,将启动DragEnter事件。 必须设置Effect属性。 拖动源和放置目标的DragDropEffects必须相等。 否则,该操作将无法进行。
Private Sub OnDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)sender.Text = e.Data.GetData(DataFormats.Text)End Sub
最后,我们有OnDragDrop方法。 在这里,我们从事件对象获取数据并将其设置为按钮Text属性。
Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)sender.DoDragDrop(sender.Text, DragDropEffects.Copy)End Sub
在OnMouseDown方法中,我们初始化了拖放过程。 我们使用DoDragDrop方法启动该过程。 DragDropEffects.Copy参数指定操作的类型。 实质上,我们可以在拖放操作期间复制文本或移动文本。

图:文本拖放
拖动图像
在最后一个示例中,我们将&拖放图像拖到窗体上。
' ZetCode Mono Visual Basic Winforms tutorial'' In this program we drag & drop' an image'' author jan bodnar' last modified May 2009' website www.zetcode.comImports System.Windows.FormsImports System.DrawingPublic Class WinVBAppInherits FormPrivate IsDragging As Boolean = FalsePrivate oldX As IntegerPrivate oldY As IntegerPrivate dropRect As RectanglePrivate picBox As PictureBoxPrivate image As BitmapPrivate brsh As BrushPublic Sub NewMe.Text = "Drag & Drop image"Me.Size = New Size(350, 250)Me.InitUIMe.CenterToScreenEnd SubPrivate Sub InitUIisDragging = FalsedropRect = New Rectangle(10, 10, 200, 160)brsh = Brushes.GraypicBox = New PictureBoxMe.LoadImagepicBox.Parent = MepicBox.Location = New Point(100, 50)picBox.Size = New Size(image.Width, image.Height)picBox.Image = imagepicBox.Cursor = Cursors.HandAddHandler Me.Paint, AddressOf Me.OnPaintAddHandler picBox.MouseDown, AddressOf Me.OnMouseDownAddHandler picBox.MouseMove, AddressOf Me.OnMouseMoveAddHandler picBox.MouseUp, AddressOf Me.OnMouseUpEnd SubPrivate Sub LoadImageTryimage = New Bitmap("image.jpg")CatchConsole.WriteLine("Error reading image")Environment.Exit(1)End TryEnd SubPrivate Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)isDragging = TrueoldX = e.XoldY = e.YEnd SubPrivate Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)If isDraggingpicBox.Top = picBox.Top + (e.Y - oldY)picBox.Left = picBox.Left + (e.X - oldX)End IfEnd SubPrivate Sub OnMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)isDragging = FalseIf dropRect.Contains(picBox.Bounds)brsh = Brushes.GoldElsebrsh = Brushes.GrayEnd IfMe.RefreshEnd SubPrivate Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)Dim g As Graphics = e.Graphicsg.FillRectangle(brsh, dropRect)End SubPublic Shared Sub MainApplication.Run(New WinVBApp)End SubEnd Class
在我们的示例中,我们有一个PictureBox,并绘制了一个灰色矩形。 如果将图片放在矩形内,则矩形的颜色变为金色。
brsh = Brushes.Gray
brsh变量保存矩形的笔刷。 默认情况下为灰色。
Private Sub LoadImageTryimage = New Bitmap("image.jpg")CatchConsole.WriteLine("Error reading image")Environment.Exit(1)End TryEnd Sub
LoadImage方法为PictureBox控件加载位图。
If dropRect.Contains(picBox.Bounds)brsh = Brushes.GoldElsebrsh = Brushes.GrayEnd If
在OnMouseUp方法中,我们确定矩形的笔刷。 如果图片框的边界在矩形内,则画笔为金色;否则,画笔为金色。 否则为灰色。
Me.Refresh
我们必须调用Refresh方法来激活新的画笔颜色。

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