Drag and drop WPF ListBox hinder ContextMenu?

I implement drag and drop from a ListBox, but I see strange behavior with ContextMenu elsewhere in the window. If you open the context menu and start dragging from the list, the context menu closes, but does not open again until you perform another drag.

It makes sense? Has anyone got any ideas on what might happen?
<ListBox Grid.Row="0" ItemsSource="{Binding SourceItems}" MultiSelectListboxDragDrop:ListBoxExtension.SelectedItemsSource="{Binding SelectedItems}" SelectionMode="Multiple" PreviewMouseLeftButtonDown="HandleLeftButtonDown" PreviewMouseLeftButtonUp="HandleLeftButtonUp" PreviewMouseMove="HandleMouseMove"/>
<ListBox Grid.Row="1" ItemsSource="{Binding DestinationItems}" AllowDrop="True" Drop="DropOnToDestination" />
<Button Grid.Row="2">
    <Button.ContextMenu>
        <ContextMenu x:Name="theContextMenu">
            <MenuItem Header="context 1"/>
            <MenuItem Header="context 2"/>
            <MenuItem Header="context 3"/>
        </ContextMenu>
    </Button.ContextMenu>
    Button with context menu
</Button>

...

public partial class Window1
{
    private bool clickedOnSourceItem;

    public Window1()
    {
        InitializeComponent();

        DataContext = new WindowViewModel();
    }

    private void DropOnToDestination(object sender, DragEventArgs e)
    {
        var viewModel = (WindowViewModel)e.Data.GetData(typeof(WindowViewModel));
        viewModel.CopySelectedItems();
    }

    private void HandleLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var sourceElement = (FrameworkElement)sender;
        var hitItem = sourceElement.InputHitTest(e.GetPosition(sourceElement)) as FrameworkElement;

        if(hitItem != null)
        {
            clickedOnSourceItem = true;
        }
    }

    private void HandleLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        clickedOnSourceItem = false;
    }

    private void HandleMouseMove(object sender, MouseEventArgs e)
    {
        if(clickedOnSourceItem)
        {
            var sourceItems = (FrameworkElement)sender;
            var viewModel = (WindowViewModel)DataContext;

            DragDrop.DoDragDrop(sourceItems, viewModel, DragDropEffects.Move);
            clickedOnSourceItem = false;
        }
    }
}
+3
source share
1 answer

It seemed that this was due to mouse capture !?

The normal sequence of events during drag and drop looks something like this:

  • PreviewMouseLeftButtonDown the handler receives a call and a ListBox.IsMouseCaptureWithin lie.
  • PreviewMouseMove . ListBox.IsMouseCaptureWithin .
  • PreviewMouseMove DragDrop.DoDragDrop - ListBox.

, , , , ...

  • PreviewMouseLeftButtonDown ListBox.IsMouseCaptureWithin .
  • PreviewMouseMove . ListBox.IsMouseCaptureWithin false.
  • - PreviewMouseMove ListBox (ListBox.IsMouseCaptureWithin )

, ListBox , , , , .

PreviewMouseLeftButtonDown, -, , , , ...

if (!contextMenuCloseComplete)
{
    sourceElement.CaptureMouse();
    return;
}

... contextMenuCloseComplete bool Closed Opened .

? - , ?

+1

Source: https://habr.com/ru/post/1719961/


All Articles