滚动时禁用拖放 [英] Disable drag and drop when scrolling

查看:141
本文介绍了滚动时禁用拖放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现拖放在WPF一个TreeView拖放功能。



一切工作正常,但是当在树状视图显示在滚动,如果我选择一个项目在树中,然后,尝试滚动(垂直或水平)在TreeView试图执行拖放操作。



有人能帮助我吗?这里是源代码:

 类TreeViewRearranger 
{
私人的TreeView mTreeView;

私人INT MOVE_TOLERANCE = 10;

私人树型视图mDraggedItem = NULL;
私人树型视图mTargetDrop = NULL;
私人DropAdorner mDropAdorner = NULL;

公共无效初始化(TreeView控件TreeView控件)
{
mTreeView =树视图;

SetupDragDropEvents();
}

私人无效SetupDragDropEvents()
{
mTreeView.MouseDown + = mTreeView_MouseDown;
mTreeView.MouseMove + = mTreeView_MouseMove;
mTreeView.DragOver + = mTreeView_DragOver;
mTreeView.Drop + = mTreeView_Drop;
mTreeView.DragEnter + = mTreeView_DragEnter;
mTreeView.DragLeave + = mTreeView_DragLeave;
}

无效mTreeView_MouseDown(对象发件人,MouseButtonEventArgs E)
{
如果(e.ChangedButton = MouseButton.Left!)
的回报;

mLastMouseDown = e.GetPosition(mTreeView);
}

无效mTreeView_MouseMove(对象发件人,MouseEventArgs E)
{
如果(e.LeftButton = MouseButtonState.Pressed!)
的回报;

点currentPosition = e.GetPosition(mTreeView);

如果((Math.Abs​​(currentPosition.X - mLastMouseDown.X)下; = MOVE_TOLERANCE)及&放大器;
(Math.Abs​​(currentPosition.Y - mLastMouseDown.Y)下= MOVE_TOLERANCE))

的回报;

的startDrag();
}

无效mTreeView_DragLeave(对象发件人,DragEventArgs E)
{
RemoveAdorners();
}

无效mTreeView_DragEnter(对象发件人,DragEventArgs E)
{
AdornerLayer层= AdornerLayer.GetAdornerLayer(mTreeView);
mDropAdorner =新DropAdorner(mTreeView);

layer.Add(mDropAdorner);
}

私人点mLastMouseDown;

私人无效的startDrag()
{
mDraggedItem = mTreeView.SelectedItem为树型视图;

如果(mDraggedItem == NULL)回报;

DragDropEffects finalDropEffect =
DragDrop.DoDragDrop(
mTreeView,mTreeView.SelectedValue,DragDropEffects.Move);

//检查目标不为空并且产品
//拖动(移动)

如果((finalDropEffect!= DragDropEffects.Move)||( mTargetDrop == NULL))
的回报;

// A将下降被接受

如果(mDraggedItem.Header.ToString()等于(mTargetDrop.Header.ToString()))
的回报;

PerformDragDrop(mDraggedItem,mTargetDrop);

mTargetDrop = NULL;
mDraggedItem = NULL;
}

私人无效PerformDragDrop(树型视图源,树型视图目标)
{
如果(来源== NULL ||目的地== NULL)
返回;

OnRearrange(源,目的);
}

私有静态树型视图GetParentTreeViewItem(DependencyObject的项目)
{
如果(项目== NULL)
返回NULL;

的DependencyObject父= VisualTreeHelper.GetParent(项目);
树型视图parentTreeViewItem =父为树型视图;
返回parentTreeViewItem? GetParentTreeViewItem(父);
}

私人无效OnRearrange(树型视图源,树型视图目标)
{
如果(来源== NULL ||目的地== NULL)
返回;

树节点sourceNode = source.Tag作为树节点;
树节点destinationNode = destination.Tag作为树节点;

树节点targetNode = destinationNode;

如果
{
树型视图parentItem = GetParentTreeViewItem(目标)(destination.IsExpanded || destination.Items.Count == 0!);

如果(parentItem == NULL)
{
targetNode = mTreeView.Tag作为树节点;
}
,否则
{
targetNode = parentItem.Tag作为树节点;
}
}

INT指数= targetNode.Children.IndexOf(destinationNode)+ 1; //索引
}

无效mTreeView_DragOver(对象发件人,DragEventArgs E)
{
进行了重新排列,从sourceNode到targetNode

点currentPosition = e.GetPosition(mTreeView);

如果((Math.Abs​​(currentPosition.X - mLastMouseDown.X)下; = MOVE_TOLERANCE)及&放大器;
(Math.Abs​​(currentPosition.Y - mLastMouseDown.Y)下= MOVE_TOLERANCE))

的回报;

//确认这是一个有效的下拉,然后储存放置目标

树型视图项= GetNearestContainer(e.OriginalSource为的UIElement);

如果(CheckDropTarget(mDraggedItem,项目))
{
e.Effects = DragDropEffects.Move;
UpdateDropAdorner(项目);
}
,否则
{
e.Effects = DragDropEffects.None;
UpdateDropAdorner(NULL);
}

e.Handled = TRUE;
}

无效mTreeView_Drop(对象发件人,DragEventArgs E)
{
e.Effects = DragDropEffects.None;
e.Handled = TRUE;

//确认这是一个有效的下拉,然后储存放置目标
树型视图targetItem = GetNearestContainer
(e.OriginalSource为的UIElement);

如果(targetItem == NULL || mDraggedItem == NULL)
的回报;

mTargetDrop = targetItem;
e.Effects = DragDropEffects.Move;

UpdateDropAdorner(mTargetDrop);

RemoveAdorners();
}

私人无效UpdateDropAdorner(树型视图targetItem)
{
mDropAdorner.UpdateTargetPosition(targetItem);
}

私人树型视图GetNearestContainer(的UIElement元素)
{
//行走了元素树到最近的树视图项。
的TreeViewItem容器=元素树型视图;
,而((容器== NULL)及和放大器;!(元= NULL))
{
元素= VisualTreeHelper.GetParent(元素)作为的UIElement;
容器=元素树型视图;
}
返回容器中;
}

私人布尔CheckDropTarget(树型视图sourceItem,树型视图targetItem)
{
如果(sourceItem == NULL || targetItem == NULL)
返回假;

如果(sourceItem.Header.ToString()等于(targetItem.Header.ToString()))
返回FALSE;

如果(targetItem.IsDescendantOf(sourceItem))
返回false;

返回真;
}

私人无效RemoveAdorners()
{
AdornerLayer层= AdornerLayer.GetAdornerLayer(mTreeView);

layer.Remove(mDropAdorner);

mDropAdorner = NULL;
}
}


解决方案

您可能有自己附加到scrollviewers ScrollChanged事件并在触发该事件禁用拖放。我还没有尝试过,但我认为,这可能是一个起点,试图

 的ScrollViewer的ScrollViewer = GetVisualChild<的ScrollViewer>( mTreeView); 
scrollViewer.ScrollChanged + =新ScrollChangedEventHandler(ScrollViewer中


I have implemented drag and drop functionality for a TreeView in WPF.

All works fine but when the scrolls are shown in the tree view, if I select an item in the tree and then and try to scroll (vertical or horizontal) the TreeView tries to perform a drag drop operation.

Somebody can help me? Here is the source code:

class TreeViewRearranger
{
    private TreeView mTreeView;

    private int MOVE_TOLERANCE = 10;

    private TreeViewItem mDraggedItem = null;
    private TreeViewItem mTargetDrop = null;
    private DropAdorner mDropAdorner = null;

    public void Initialize(TreeView treeView)
    {
        mTreeView = treeView;

        SetupDragDropEvents();
    }

    private void SetupDragDropEvents()
    {
        mTreeView.MouseDown += mTreeView_MouseDown;
        mTreeView.MouseMove += mTreeView_MouseMove;
        mTreeView.DragOver += mTreeView_DragOver;
        mTreeView.Drop += mTreeView_Drop;
        mTreeView.DragEnter += mTreeView_DragEnter;
        mTreeView.DragLeave += mTreeView_DragLeave;
    }

    void mTreeView_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ChangedButton != MouseButton.Left)
            return;

        mLastMouseDown = e.GetPosition(mTreeView);
    }

    void mTreeView_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton != MouseButtonState.Pressed)
            return;

        Point currentPosition = e.GetPosition(mTreeView);

        if ((Math.Abs(currentPosition.X - mLastMouseDown.X) <= MOVE_TOLERANCE) &&
            (Math.Abs(currentPosition.Y - mLastMouseDown.Y) <= MOVE_TOLERANCE))

            return;

        StartDrag();
    }

    void mTreeView_DragLeave(object sender, DragEventArgs e)
    {
        RemoveAdorners();
    }

    void mTreeView_DragEnter(object sender, DragEventArgs e)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(mTreeView);
        mDropAdorner = new DropAdorner(mTreeView);

        layer.Add(mDropAdorner);
    }

    private Point mLastMouseDown;

    private void StartDrag()
    {
        mDraggedItem = mTreeView.SelectedItem as TreeViewItem;

        if (mDraggedItem == null) return;

        DragDropEffects finalDropEffect =
            DragDrop.DoDragDrop(
                mTreeView, mTreeView.SelectedValue, DragDropEffects.Move);

        // Check that target is not null and item is 
        // dragging(moving)

        if ((finalDropEffect != DragDropEffects.Move) || (mTargetDrop == null))
            return;

        // A Move drop was accepted

        if (mDraggedItem.Header.ToString().Equals(mTargetDrop.Header.ToString()))
            return;

        PerformDragDrop(mDraggedItem, mTargetDrop);

        mTargetDrop = null;
        mDraggedItem = null;
    }

    private void PerformDragDrop(TreeViewItem source, TreeViewItem destination)
    {
        if (source == null || destination == null)
            return;

        OnRearrange(source, destination);
    }

    private static TreeViewItem GetParentTreeViewItem(DependencyObject item)
    {
        if (item == null)
            return null;

        DependencyObject parent = VisualTreeHelper.GetParent(item);
        TreeViewItem parentTreeViewItem = parent as TreeViewItem;
        return parentTreeViewItem ?? GetParentTreeViewItem(parent);
    }

    private void OnRearrange(TreeViewItem source, TreeViewItem destination)
    {
        if (source == null || destination == null)
            return;

        TreeNode sourceNode = source.Tag as TreeNode;
        TreeNode destinationNode = destination.Tag as TreeNode;

        TreeNode targetNode = destinationNode;

        if (!destination.IsExpanded || destination.Items.Count == 0)
        {
            TreeViewItem parentItem = GetParentTreeViewItem(destination);

            if (parentItem == null)
            {
                targetNode = mTreeView.Tag as TreeNode;
            }
            else
            {
                targetNode = parentItem.Tag as TreeNode;
            }
        }

        int index = targetNode.Children.IndexOf(destinationNode) + 1;

        // performed a rearrange from sourceNode to targetNode at index
    }

    void mTreeView_DragOver(object sender, DragEventArgs e)
    {
        Point currentPosition = e.GetPosition(mTreeView);

        if ((Math.Abs(currentPosition.X - mLastMouseDown.X) <= MOVE_TOLERANCE) &&
            (Math.Abs(currentPosition.Y - mLastMouseDown.Y) <= MOVE_TOLERANCE))

            return;

        // Verify that this is a valid drop and then store the drop target

        TreeViewItem item = GetNearestContainer(e.OriginalSource as UIElement);

        if (CheckDropTarget(mDraggedItem, item))
        {
            e.Effects = DragDropEffects.Move;
            UpdateDropAdorner(item);
        }
        else
        {
            e.Effects = DragDropEffects.None;
            UpdateDropAdorner(null);
        }

        e.Handled = true;
    }

    void mTreeView_Drop(object sender, DragEventArgs e)
    {
        e.Effects = DragDropEffects.None;
        e.Handled = true;

        // Verify that this is a valid drop and then store the drop target
        TreeViewItem targetItem = GetNearestContainer
            (e.OriginalSource as UIElement);

        if (targetItem == null || mDraggedItem == null)
            return;

        mTargetDrop = targetItem;
        e.Effects = DragDropEffects.Move;

        UpdateDropAdorner(mTargetDrop);

        RemoveAdorners();
    }

    private void UpdateDropAdorner(TreeViewItem targetItem)
    {
        mDropAdorner.UpdateTargetPosition(targetItem);
    }

    private TreeViewItem GetNearestContainer(UIElement element)
    {
        // Walk up the element tree to the nearest tree view item.
        TreeViewItem container = element as TreeViewItem;
        while ((container == null) && (element != null))
        {
            element = VisualTreeHelper.GetParent(element) as UIElement;
            container = element as TreeViewItem;
        }
        return container;
    }

    private bool CheckDropTarget(TreeViewItem sourceItem, TreeViewItem targetItem)
    {
        if (sourceItem == null || targetItem == null)
            return false;

        if (sourceItem.Header.ToString().Equals(targetItem.Header.ToString()))
            return false;

        if (targetItem.IsDescendantOf(sourceItem))
            return false;

        return true;
    }

    private void RemoveAdorners()
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(mTreeView);

        layer.Remove(mDropAdorner);

        mDropAdorner = null;
    }
}

解决方案

You may have to attach yourself to the scrollviewers ScrollChanged event and when that event is triggered you disable drag and drop. I haven't tried it but I think that it might be a starting place to try

ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(mTreeView);
        scrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer

这篇关于滚动时禁用拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆