C# 在滚动时禁用拖放
我已经在WPF中为TreeView实现了拖放功能 所有工作正常,但当滚动显示在树状视图中时,如果我在树中选择一个项目,然后尝试滚动(垂直或水平),树状视图将尝试执行拖放操作 以下是源代码:C# 在滚动时禁用拖放,c#,wpf,drag-and-drop,scroll,treeview,C#,Wpf,Drag And Drop,Scroll,Treeview,我已经在WPF中为TreeView实现了拖放功能 所有工作正常,但当滚动显示在树状视图中时,如果我在树中选择一个项目,然后尝试滚动(垂直或水平),树状视图将尝试执行拖放操作 以下是源代码: class TreeViewRearranger { private TreeView mTreeView; private int MOVE_TOLERANCE = 10; private TreeViewItem mDraggedItem = null; private
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;
}
}
类TreeViewArranger
{
私人TreeView mTreeView;
私有int MOVE_公差=10;
私有TreeViewItem mDraggedItem=null;
私有TreeViewItem mTargetDrop=null;
私有DropAdorner mDropAdorner=null;
公共无效初始化(TreeView TreeView)
{
mTreeView=treeView;
SetupDragDropEvents();
}
专用void SetupDragDropEvents()
{
mTreeView.MouseDown+=mTreeView\u MouseDown;
mTreeView.MouseMove+=mTreeView\u MouseMove;
mTreeView.DragOver+=mTreeView\u DragOver;
mTreeView.Drop+=mTreeView\u Drop;
mTreeView.DragEnter+=mTreeView\u DragEnter;
mTreeView.DragLeave+=mTreeView\u DragLeave;
}
void mTreeView_MouseDown(对象发送器,鼠标按钮ventargs e)
{
if(例如ChangedButton!=鼠标按钮左)
返回;
mLastMouseDown=e.GetPosition(mTreeView);
}
void mTreeView\u MouseMove(对象发送方,MouseEventArgs e)
{
如果(例如LeftButton!=鼠标按钮状态已按下)
返回;
点currentPosition=e.GetPosition(mTreeView);
如果((Math.Abs(currentPosition.X-mLastMouseDown.X)您可能必须将自己附加到ScrollViewer ScrollChanged事件,并且在触发该事件时禁用拖放。我没有尝试过,但我认为这可能是一个尝试的起点
ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(mTreeView);
scrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer
ScrollViewer ScrollViewer=GetVisualChild(mTreeView);
scrollViewer.ScrollChanged+=新的ScrollChangedEventHandler(scrollViewer