I have a ListBox, where child items are expanders. I need realize DragDrop event for this. If I write in XAML
<ListBox PreviewMouseLeftButtonDown="StartDragDrop">
, StartDragDrop method is works good, but child expanders are cannot be expanded. If I write
<ListBox MouseLeftButtonDown="StartDragDrop">
, child expanders are works correct, but StartDragDrop method is not works. I think the problem is relates with bubble and tunnel events, but I dont know clear solution. I need both, StartDragDrop method and ListBox child expanders Expand method, are work correct. What should I do?
The main idea is call DoDragDrop mathod at PreviewMouseMove() event, when moving offset is larger than somehow value.
1) Here the list box:
<ListBox AllowDrop="True" Drop=" ListBox_Drop" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" PreviewMouseMove="ListBox_PreviewMouseMove">
ListBoxItems are Expanders, that cannot expand if we implement DragAndDrop.
2) Now we must add 2 variables (I use VB.NET):
Private isDragging As Boolean = False 'flag: is drag operation in process?'
Private dragStartPoint As Point 'coords of dragging start.'
3) Remember start point coords by preview mouse click:
Private Sub ListBox_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
dragStartPoint = e.GetPosition(Me)
End Sub
4) On PreviewMouseMove get moving start point to current moving point offset. If offset is larger than some value, we initiate DragAndDrop operation and set flag isDragging to remember this.
Private Sub ListBox_PreviewMouseMove(sender As System.Object, e As MouseEventArgs)
If e.LeftButton = MouseButtonState.Pressed Then
Dim diff As Vector = Point.Subtract(dragStartPoint, e.GetPosition(Me))
If (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance) OrElse (Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) Then
If Not isDragging Then
isDragging = True 'the flag is active until drop event raises.'
Dim lstBox As ListBox = TryCast(sender, ListBox) 'get sender ListBox'
If lstBox IsNot Nothing Then
Dim data As Object = GetDataFromListBox(lstBox, e.GetPosition(lstBox)) 'get data for drag-and-drop; need to be realized; there are some realizations at Stackoverflow.com presented.'
Dim effects As DragDropEffects = DragDrop.DoDragDrop(lstBox, data, DragDropEffects.Move) 'initiate drag-and-drop.'
End If
End If
End If
End If
End Sub
5) Proccessing drop operation:
Private Sub ListBox_Drop(sender As Object, e As DragEventArgs)
isDragging = False 'reset isDragging flag.'
Dim lstBox As ListBox = TryCast(sender, ListBox) 'get sender ListBox.'
If lstBox IsNot Nothing Then
Dim myObj As MyClass = TryCast(e.Data.GetData(GetType(MyClass)), MyClass)
'...some actions'
End If
End Sub
I've realized this idea and it's works exactly I was need: