【问题标题】:How do I tell if a Drag Drop has ended in Winforms?如何判断拖放是否已在 Winforms 中结束?
【发布时间】:2015-10-10 01:38:33
【问题描述】:

我如何判断一个 Drag Drop 是否已结束 WinForms .net。当拖放正在进行时,我需要阻止部分表单刷新它的数据视图。

我尝试过使用标志,但我似乎没有捕获我需要的所有事件,以使标志与拖放进度保持同步。具体来说,我无法判断拖放操作何时结束而没有完成拖放,即当用户将项目放在允许 drop = false 的控件上时,或者当用户按下 ESC 键时。

我看过这个问题:-

Check if a drag&drop is in progress

但这并不能令人满意地解决我的问题(如果有人给我这个问题的答案,我会连同我已有的答案一起回答那个问题)。

【问题讨论】:

    标签: .net winforms


    【解决方案1】:

    我没有接受者,最终想通了。

    答案是监控 QueryContinueDrag 事件。此事件在拖放操作期间不断触发。 QueryContinueDragEventArgs 包含枚举类型 DragAction 的 Action 属性,该属性可以是 DragAction.Cancel、DragAction.Drop 或 DragAction.Continue。它是一个读/写属性,以允许您更改标准行为(我们不需要这个)。

    此示例代码假定 DragDropInProgress 标志在拖放开始时设置,并在拖放成功完成时重置。它捕捉到 DragDrop 结束,因为用户在没有经过拖放目标(拖放目标是 MyControl1 和 MyControl2)的情况下松开鼠标或取消了拖放。如果您不关心 DragDropInProgressFlag 是否在 DragDrop 事件触发之前被重置,您可以省略命中测试并重置标志。

    Private Sub MyControl_QueryContinueDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.QueryContinueDragEventArgs) Handles MyControl.QueryContinueDrag
    
        Dim MousePointerLocation As Point = MousePosition
    
        If e.Action = DragAction.Cancel Then '' User pressed the Escape button
            DragDropInProgressFlag = False
        End If
    
        If e.Action = DragAction.Drop Then
            If Not HitTest(new {MyControl1, MyControl2}, MousePointerLocation) Then
                DragDropInProgressFlag = False
            End If
        End If
    
    End Sub
    
    Private Function HitTest(ByVal ctls() As Control, ByVal p As Point) As Boolean
    
        HitTest = False
    
        For Each ctl In ctls
            Dim ClientPoint As Point = ctl.PointToClient(p)
            HitTest = HitTest Or (ClientPoint.X >= 0 AndAlso ClientPoint.Y >= 0 AndAlso ClientPoint.X <= ctl.Width AndAlso ClientPoint.Y <= ctl.Height)
            If HitTest Then Exit For
        Next
    
    End Function
    

    在此示例中,HitTest 是一个 rountine,它获取鼠标位置(屏幕坐标)和控件数组,如果鼠标位置在任何控件矩形中,则通过传递 True 的数组进行筛选。

    【讨论】:

    • 你太棒了!正是我需要一个好的实现来对特定控件进行命中测试。聪明。
    • If clt.ClientRectangle.Contains(ClientPoint) Then : HitTest = True : Exit For : End If
    • :添加只是为了显示换行符(即使语句将在显示时起作用)。
    • :) 很高兴为您提供帮助!不要经常被称为 AWESOME...随意使用更具可读性的代码进行编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    相关资源
    最近更新 更多