2

私はツリービューを持っています。TreeViewItems に ContextMenu を設定しました。アイテムを右クリックして 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;
    }
4

3 に答える 3

1

問題が見つかりました:StartDragメソッド "var temp = TemplateTreeView.SelectedItemasQuestionListItem"でvartemp= GetItemAtLocation(e.GetPosition(TemplateTreeView));に変更しました。

于 2012-10-12T06:55:03.497 に答える
1

投稿したコードから判断すると、シナリオでは StartDrag メソッドを呼び出すべきではありません。しかし、ドロップアンドドロップ操作になるため、明らかに呼び出されます。そこにブレークポイントを配置すると、なぜそれが呼び出されたのかがわかります。

ちなみに、このコード

_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(sender as IInputElement); を置き換えることもできます。e.GetPosition(System.Windows.Application.Current.MainWindow) によるステートメント

于 2012-10-11T15:19:51.320 に答える