You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TreeView折叠/展开根节点时误触发拖拽问题及解决

WPF TreeView折叠/展开根节点时误触发拖拽的问题解决

问题描述

在未选中任何项的情况下折叠或展开TreeView的根节点时,应用程序会误触发拖拽操作,导致droppedData始终被初始化为最后一次移动的MyItem,即使没有选中任何项。

问题代码

private void TreeView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var treeViewItem = GetNearestContainer(e.OriginalSource as UIElement);
    if (treeViewItem == null) return;

    MyItem clickedItem = treeViewItem.DataContext as MyItem;
    if (clickedItem != null && clickedItem.CanBeDragged)
    {
        _draggedItem = clickedItem;
    }
}

private void TreeView_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed && _draggedItem != null)
    {
        // 开始拖拽
        DragDrop.DoDragDrop(MyTreeView, _draggedItem, DragDropEffects.Move);
        _draggedItem = null; // 拖拽完成后清空项
    }
}

解决方案

在启动拖拽操作前,检查鼠标是否移动了系统定义的最小拖拽距离。只有当鼠标水平或垂直移动距离超过阈值时,才触发拖拽逻辑,避免折叠/展开根节点时的微小鼠标移动误触发拖拽。

修正后的代码

private Point? _mouseDownPosition;

private void TreeView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var treeViewItem = GetNearestContainer(e.OriginalSource as UIElement);
    if (treeViewItem == null) return;

    MyItem clickedItem = treeViewItem.DataContext as MyItem;
    if (clickedItem != null && clickedItem.CanBeDragged)
    {
        _draggedItem = clickedItem;
    }

    // 记录鼠标按下时的位置
    _mouseDownPosition = e.GetPosition(MyTreeView);
}

private void TreeView_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed && _draggedItem != null)
    {
        // 在启动拖拽前检查鼠标是否移动了足够距离
        var mouseMovePosition = e.GetPosition(MyTreeView);
        var diff = _mouseDownPosition - mouseMovePosition;
        if (_mouseDownPosition.HasValue && 
            (Math.Abs(diff.Value.X) > SystemParameters.MinimumHorizontalDragDistance ||
             Math.Abs(diff.Value.Y) > SystemParameters.MinimumVerticalDragDistance))
        {
            // 开始拖拽
            DragDrop.DoDragDrop(MyTreeView, _draggedItem, DragDropEffects.Move);
            _draggedItem = null; // 拖拽完成后清空项
            _mouseDownPosition = null; // 清空鼠标按下位置记录
        }
    }
}

内容的提问来源于stack exchange,提问作者user22345381

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:29:53