我有一个包含 2 个面板的表格:
Panel1.BackColor 为 Color.Red
Panel2.BackColor为Color.Blue
将 panel1 拖到 panel2 时,panel2 必须采用 panel1 的颜色
启动拖动操作面板1时必须将颜色更改为白色
拖放完成后,panel1 必须返回红色。
这一切都完成了,但我还是怀念这个:
如果取消拖放操作(在其他控件上拖放、按 ESC 等),则 panel2 的颜色保持白色,不会恢复为 Color.Red。
我该如何实现这个目标?
我尝试查看 QueryContinueDrag,但似乎找不到解决方案。
这是我的代码:
Public Class Form1
Private dragBoxFromMouseDown As Rectangle
Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) Handles Panel1.MouseDown
Dim dragSize As Size = SystemInformation.DragSize
dragBoxFromMouseDown = New Rectangle(New Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize)
End Sub
Private Sub Panel1_MouseMove(sender As Object, e As MouseEventArgs) Handles Panel1.MouseMove
If ((e.Button And MouseButtons.Left) = MouseButtons.Left) Then
If (Rectangle.op_Inequality(dragBoxFromMouseDown, Rectangle.Empty) And Not dragBoxFromMouseDown.Contains(e.X, e.Y)) Then
Panel1.BackColor = Color.White
Panel1.DoDragDrop(sender.name, DragDropEffects.All)
End If
End If
End Sub
Private Sub Panel2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel2.DragEnter
If e.Data.GetData(DataFormats.Text).contains("Panel1") Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub Panel2_DragDrop(sender As Object, e As DragEventArgs) Handles Panel2.DragDrop
Panel2.BackColor = Me.Controls(e.Data.GetData(DataFormats.Text)).backcolor
Me.Controls(e.Data.GetData(DataFormats.Text)).backcolor = Color.Red
End Sub
End Class
正如您所提到的,您应该处理源面板的 QueryContinueDrag 事件,以确定正在执行什么操作。可能是
Continue
、Drop
或 Cancel
。DragAction.Drop
或 DragAction.Cancel
时恢复源控件的背景颜色。
我重构了这里提供的一些代码,因为它包含一些奇怪的东西。
例如,您可以简单地将 Control 实例传递给
DoDragDrop()
方法,然后使用 e.Data.GetDataPresent()
验证它是否包含您要处理的 Type。Private panelQueryDragPosition As Point
Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) Handles Panel1.MouseDown
panelQueryDragPosition = e.Location
End Sub
Private Sub Panel1_MouseMove(sender As Object, e As MouseEventArgs) Handles Panel1.MouseMove
If e.Button = MouseButtons.Left AndAlso
(Math.Abs(e.X - panelQueryDragPosition.X) > SystemInformation.DragSize.Width OrElse
Math.Abs(e.Y - panelQueryDragPosition.Y) > SystemInformation.DragSize.Height) Then
Dim ctl = DirectCast(sender, Panel) ' The source Control cannot be null here
ctl.BackColor = Color.White
ctl.DoDragDrop(ctl, DragDropEffects.Copy)
End If
End Sub
Private Sub Panel1_QueryContinueDrag(sender As Object, e As QueryContinueDragEventArgs) Handles Panel1.QueryContinueDrag
If e.Action = DragAction.Drop OrElse e.Action = DragAction.Cancel Then
Dim ctl = DirectCast(sender, Control)
If ctl IsNot Nothing Then ctl.BackColor = Color.Red
End If
End Sub
Private Sub Panel2_DragEnter(sender As Object, e As DragEventArgs) Handles Panel2.DragEnter
If e.Data IsNot Nothing AndAlso e.Data.GetDataPresent(GetType(Panel)) Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub Panel2_DragDrop(sender As Object, e As DragEventArgs) Handles Panel2.DragDrop
Dim panel = DirectCast(sender, Panel)
If panel IsNot Nothing AndAlso e.Data IsNot Nothing AndAlso e.Data.GetDataPresent(GetType(Panel)) Then
Dim sourceControl = DirectCast(e.Data.GetData(GetType(Panel)), Panel)
panel.BackColor = sourceControl.BackColor
End If
End Sub