Как предотвратить «перетаскивание» себя в таблицу данных? - PullRequest
1 голос
/ 05 марта 2009

Я реализую функцию перетаскивания между двумя представлениями данных. Это работает, как задумано, с одним исключением: возможно перетаскивание в пределах одного и того же вида данных Это приводит к дублированию строк. Я хочу ограничить функциональность, чтобы я мог перетаскивать только одно представление данных в другое. Кто-нибудь знает, как этого можно достичь? Я предполагаю, что требуется какой-то тест на попадание, но я не уверен, как это реализовать ...

Код, который я использую, выглядит следующим образом:

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

Ответы [ 5 ]

1 голос
/ 05 марта 2009

Просто быстрая идея. Что если при запуске перетаскивания вы держите имя исходной сетки. Когда вы делаете удаление, проверьте имя, если это один и тот же объект, тогда не разрешайте удаление.

0 голосов
/ 09 сентября 2015

Установка флага в false в событии MouseLeave не работала правильно для меня. MouseLeave продолжал вызываться, как только я позвонил DoDragDrop.

Наконец-то я получил правильную работу следующим образом:

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;

Карлос Мериге

0 голосов
/ 01 августа 2012

Один из способов - сохранить строковое описание того, что вы перетаскиваете, в 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
0 голосов
/ 12 июля 2011

Я не смог найти хорошего ответа на это, хотя, похоже, это часто встречающаяся проблема. Поэтому я использовал ответ Гбианки следующим образом:

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 ...
}

Теперь я действительно сделал это специально для предотвращения "блуждающих" двойных щелчков, когда мышь немного перемещается между двойными щелчками. Это предотвращает двойные щелчки, регистрирующиеся как перетаскиваемые объекты, а также отвечает на вопрос ОП.

Имейте в виду, это не работает 100% времени. По-видимому, некоторые события «потеряны» в 1 из 20 случаев. Я не определил, что именно меняется в тех ситуациях, когда он регистрирует каплю на себя. В случае предотвращения двойного щелчка, регистрируемого как перетаскивание, 95% достаточно, потому что он только что был установлен, чтобы избежать раздражения. Если вам нужно что-то, что на 100% эффективно, вам, возможно, придется попробовать что-то еще или выяснить, почему это не работает в этих нескольких случаях.

0 голосов
/ 05 марта 2009

Просто проверьте равенство ссылок при отбрасывании. Примерно так:

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