мы используем шаблон MVVM в нашем приложении и в окне, у нас есть два TreeView
, позволяющие перетаскивать элементы из первого и отбрасывать это на втором дереве. Чтобы избежать кода позади, мы используем поведение для привязки перетаскивания к ViewModel.
Поведение реализовано в значительной степени как этот примери работает как шарм, с одной ошибкой.
Сценарий представляет собой дерево, которое больше отображающего его окна, поэтому оно имеет вертикальную полосу прокрутки. Когда элемент выбран и пользователь хочет выполнить прокрутку, программа начинает перетаскивание (что предотвращает реальную прокрутку и, следовательно, не то, что нам нужно).
В этом нет ничего удивительного, поскольку полоса прокрутки содержится в элементе управления TreeView
. Но я не могу безопасно определить, находится ли мышь над полосой прокрутки или нет.
Элементы TreeViewItem
представлены темой с использованием границ, панелей и т. д., поэтому простой InputHitTest
не так прост, как может показаться.
Кто-нибудь уже сталкивался с такой же проблемой?
Если для решения проблемы требуется больше кода, я могу вставить несколько строк из .xaml.
Редактировать
Включение ссылки Николая Я решил проблему, используя метод IsMouseOverScrollbar
, если у кого-то возникнет эта проблема в будущем, код выше должен быть изменен следующим образом:
private static void PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed || startPoint == null)
return;
if (!HasMouseMovedFarEnough(e))
return;
if (IsMouseOverScrollbar(sender, e.GetPosition(sender as IInputElement)))
{
startPoint = null;
return;
}
var dependencyObject = (FrameworkElement)sender;
var dataContext = dependencyObject.GetValue(FrameworkElement.DataContextProperty);
var dragSource = GetDragSource(dependencyObject);
if (dragSource.GetDragEffects(dataContext) == DragDropEffects.None)
return;
DragDrop.DoDragDrop(
dependencyObject, dragSource.GetData(dataContext), dragSource.GetDragEffects(dataContext));
}
private static bool IsMouseOverScrollbar(object sender, Point mousePosition)
{
if (sender is Visual)
{
HitTestResult hit = VisualTreeHelper.HitTest(sender as Visual, mousePosition);
if (hit == null) return false;
DependencyObject dObj = hit.VisualHit;
while(dObj != null)
{
if (dObj is ScrollBar) return true;
if ((dObj is Visual) || (dObj is Visual3D)) dObj = VisualTreeHelper.GetParent(dObj);
else dObj = LogicalTreeHelper.GetParent(dObj);
}
}
return false;
}