WPF-treeview-拖放和上下文菜单问题

WPF-treeview-拖放和上下文菜单问题,wpf,drag-and-drop,treeview,Wpf,Drag And Drop,Treeview,我有一个树景。我在树视图项上设置了一个上下文菜单。当我通过右键单击一个项目并选择另一个项目(当ContextMenu打开时)来打开ContextMenu时,我希望刚才单击的项目不做任何操作就被选中。 相反,框架认为我想拖动打开ContextMenu的项,并因此调用Drop处理程序。 我怎样才能解决这个问题。谢谢 private void TreeViewPreviewMouseMove(object sender, MouseEventArgs e) { if (e.

我有一个树景。我在树视图项上设置了一个上下文菜单。当我通过右键单击一个项目并选择另一个项目(当ContextMenu打开时)来打开ContextMenu时,我希望刚才单击的项目不做任何操作就被选中。 相反,框架认为我想拖动打开ContextMenu的项,并因此调用Drop处理程序。 我怎样才能解决这个问题。谢谢

  private void TreeViewPreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed && !_isDragging)
        {
            var position = e.GetPosition(sender as IInputElement);
            if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
                Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
            {
                StartDrag();
            }
        }  
    }

    private void TreeViewPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _startPoint = e.GetPosition(sender as IInputElement);
    }

    private void TemplateTreeViewDrop(object sender, DragEventArgs e)
    {
        if (_isDragging && (e.Source as TreeView) != null)
        {                
          dragQuestion = e.Data.GetData(typeof(QuestionListItem)) as QuestionListItem;
          dropQuestion = GetItemAtLocation(e.GetPosition(TemplateTreeView));
            if (dragQuestion != null && dropQuestion != null && dragQuestion!=dropQuestion)
            {
                viewModel.MoveQuestion(dragQuestion, dropQuestion);
            }
        }
        e.Handled = true;
        dragQuestion = null;
    }

    private void StartDrag()
    {
        var temp = TemplateTreeView.SelectedItem as QuestionListItem;
        if(temp == null) return;

        _isDragging = true;
        var data = new DataObject(temp);
        DragDrop.DoDragDrop(TemplateTreeView, data, DragDropEffects.Move);
        _isDragging = false;
    }

从您发布的代码判断,在您的场景中不应该调用StartDrag方法。但是它显然是被调用的,因为您最终得到了一个drop&drop操作。在那里放置一个断点,您应该知道为什么会调用它

另一方面,这个代码

_isDragging = true;
var data = new DataObject(temp);
DragDrop.DoDragDrop(TemplateTreeView, data, DragDropEffects.Move);
_isDragging = false;
这是不安全的。您应该使用try/finally:

_isDragging = true;

try
{
    var data = new DataObject(temp);
    DragDrop.DoDragDrop(TemplateTreeView, data, DragDropEffects.Move);
}
finally
{
    _isDragging = false;
}

编辑:正如Dtex建议的那样,您也可以尝试替换e.GetPosition(发送者为IIInputElement);e.GetPosition(System.Windows.Application.Current.MainWindow)的语句

我发现了问题:在StartDrag方法“var temp=TemplateTreeView.SelectedItem as QuestionListItem”中,我使用var temp=GetItemAtLocation(e.GetPosition(TemplateTreeView))进行了更改

尝试检查
上下文菜单。在
StartDrag
之前可见

我猜在以下语句中_startPoint=e.GetPosition(发送方作为IIInputElement);var position=e.GetPosition(发送方作为IIInputElement);发件人对象不相同。你要确保你得到了相对于同一个物体的坐标。这似乎是一个很好的猜测Dtex。我的DragDropController实际上执行e.GetPosition(System.Windows.Application.Current.MainWindow)以避免任何问题。谢谢,我在考虑了您的评论后重构了代码。