【问题标题】:How to I prevent 'self' drag and drop in a datagridview?如何防止在datagridview中“自我”拖放?
【发布时间】:2009-03-05 11:29:39
【问题描述】:

我正在两个数据网格视图之间实现拖放功能。这可以按预期工作,但有一个例外:可以在同一个 datagridview 中拖放。这会导致重复的行。我想限制功能,以便我只能从一个 datagridview 拖动到另一个。有谁知道如何做到这一点?我猜需要某种命中测试,但我不知道如何实现这个......

我使用的代码如下:

Private Sub dgvFMAvailable_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgvFMAvailable.MouseMove

    If e.Button = Windows.Forms.MouseButtons.Left Then
        Me.dgvFMAvailable.DoDragDrop(Me.dgvFMAvailable.SelectedRows, DragDropEffects.Move)
    End If

End Sub

Private Sub dgvFMSelected_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles dgvFMSelected.DragDrop

    Try
        Me.SelectFM(CType(e.Data.GetData(GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection))

    Finally
        e.Effect = DragDropEffects.None
    End Try

End Sub

【问题讨论】:

    标签: vb.net datagridview drag-and-drop


    【解决方案1】:

    只是一个快速的想法。如果当你开始拖动时你持有原始网格的名称怎么办。放置时检查名称,如果它们是同一个对象,则不允许放置。

    【讨论】:

      【解决方案2】:

      删除时只需测试引用是否相等。像这样的:

      If Object.ReferenceEquals(droppedThing, thingWhereItWasDropped)
          ' Don't drop it
      Else
          ' Drop it
      End If
      

      【讨论】:

      • 我怎么知道我丢的东西是从哪里来的?
      • @R. Martinho Fernandes,我也很好奇。如何获得这两个值??
      【解决方案3】:

      我找不到一个好的答案,尽管这似乎是一个经常遇到的问题。所以我用gbianchi的回答如下:

      public bool DraggingFromFileLinkDGV { get; set; }
      void grdFiles_MouseDown(object sender, MouseEventArgs e)
      {
          this.DraggingFromFileLinkDGV = true;
      }
      void grdFiles_MouseLeave(object sender, EventArgs e)
      {
          this.DraggingFromFileLinkDGV = false;
      }
      
      void grdFiles_DragDrop(object sender, DragEventArgs e)
      {
          // Avoid DragDrop's on jittery DoubleClicks
          if (this.DraggingFromFileLinkDGV) return;
      
          // Your DragDrop code here ...
      }
      

      现在,我实际上这样做是为了防止鼠标在双击之间移动一点的“徘徊”双击。这可以防止双击注册为拖放以及回答 OP 问题。

      请注意,它似乎并非 100% 有效。显然,某些事件在 20 个案例中只有 1 个“丢失”。我还没有确切地确定在它自己注册下降的情况下会发生什么变化。在防止双击注册为拖放的情况下,95% 就足够了,因为它只是为了避免烦恼而放置到位。如果您需要 100% 有效的东西,您可能需要尝试其他方法或找出在这少数情况下它不起作用的原因。

      【讨论】:

        【解决方案4】:

        一种方法是在开始拖动时将要拖动的内容的字符串描述存储在 DataObject 中,即:

        Dim dataObj As New DataObject
        ...
        dataObj.SetText(G_SELF_DRAG_DROP_FLAG)
        

        然后在 DragEnter 上检查标志是否存在:

        Public Sub ProcessAttachment_DragEnter(ByRef e As System.Windows.Forms.DragEventArgs)
        
            ' prevent dragging onto self
            Dim s = e.Data.GetData(DataFormats.Text)
            If s IsNot Nothing Then
                If s.contains(G_SELF_DRAG_DROP_FLAG) Then
                    e.Effect = DragDropEffects.None
                    Exit Sub
                End If
            End If
        
            ...
        
        End Sub
        

        【讨论】:

          【解决方案5】:

          MouseLeave 事件中将标志设置为 false 对我来说无法正常工作。我一打电话给DoDragDrop,就一直打电话给MouseLeave

          我终于让它正常工作了:

          A) I create a private bool DraggingFromHere flag
          B) Right before calling DoDragDrop, I set this.DraggingFromHere = true
          C) In the MouseUp event, I set this.DraggingFromHere = false
          D) In the DragDro event, I simply to this:
              if(this.DraggingFromHere) return;
          

          卡洛斯·梅里赫

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-08-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多