当前位置: 动力学知识库 > 问答 > 编程问答 >

WPF: ListBoxItem with expander cannot expand after adding PreviewMouseLeftButtonDown event handler to parent ListBox

问题描述:

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?

网友答案:

you're partially right supposing, that it has to do something with tunneling and bubbling. The tunneling (with preview) event for the outer control is executed before the bubbling (without preview) event. But it doesn't prevent the latter from being executed. This only holds true, when somewhere in the whole event chain e.Handled is set to true. See this example:

XAML:

<Border Background="Red" PreviewMouseMove="OnPreviewMouseMove"> 
  <Border Background="Blue" MouseMove="OnMouseMove" />
</Border>

C#

private void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
  Debug.WriteLine("Preview outer");
  e.Handled = true;  // this prevents OnMouseMove from being executed
}

private void OnMouseMove(object sender, MouseEventArgs e)
{
  Debug.WriteLine("NoPreview inner");
}

If you delete the line "e.Handled = true;", OnMouseMove will be hit. If you don't set this yourself, consider, that a call to base."event-name" might do it.

Hope it helps.

Jürgen

网友答案:

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:

  • on MouseLeftButtonClick ListBoxItems with Expanders are expands and collapses,
  • on MouseMove with pressed left button DragAndDrop operation is works, ListBoxItems are able to be sorted.
分享给朋友:
您可能感兴趣的文章:
随机阅读: