好球员,我一直在抓我的头就像疯了这个问题,并已经花了好几个小时,试图研究它是如何工作的,但我还没有找到答案,如果你想看到我的任何SRC的随意问它和我会看到,如果我可以提供帮助。
基本上我遇到的问题是,我有一个TreeView
在我的应用程序,即文件夹:
Catalog
Brands
Nike
Adidas
Lactose
Styles
Sandles
Trainers
Boots
我试图解决的问题是,当我拖动周围的文件夹(这是我处理DragDropManager
类),我无法或上下滚动(只显示一个可爱的停车标志)。 我也无法将树视图中居然找到一个滚动条,所以我不能确定是如何产生它(这不是我自己的软件,我最近已经开始为一家公司工作,所以我不熟悉的代码,并没有其他人似乎知道。)
这是一个问题,如果我想从最顶部移动的东西到最底部。
滚动工作正常,对自己没有拖动正在做。
如果有人希望看到我的代码任何部分随意问,因为我不确定什么实际显示你们。
我走过了好几篇文章读和我刚刚离开抓我的头。
我已经创建了一个附加属性为实现这一行为,在这里看看我的文章 -
自动滚动容器附加的行为,而这样做拖放
主要逻辑是这样的 -
private static void OnContainerPreviewDragOver(object sender, DragEventArgs e)
{
FrameworkElement container = sender as FrameworkElement;
if (container == null) { return; }
ScrollViewer scrollViewer = GetFirstVisualChild<ScrollViewer>(container);
if (scrollViewer == null) { return; }
double tolerance = 60;
double verticalPos = e.GetPosition(container).Y;
double offset = 20;
if (verticalPos < tolerance) // Top of visible list?
{
//Scroll up
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset);
}
else if (verticalPos > container.ActualHeight - tolerance) //Bottom of visible list?
{
//Scroll down
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset);
}
}
在如此相似的问题(虽然它们大多为ListBox
/ ListView
,但应该工作TreeView
太) -
WPF列表框自动滚动的同时拖动
WPF的ListView数据绑定拖/放自动滚屏
WPF拖动以滚动无法正常工作
我知道这个问题真的老了,但这里是MVVM方式附加属性:
using System.Windows;
using System.Windows.Controls;
namespace AndroidCtrlUI.XTools.Behaviors
{
///<summary>
/// TreeItemAttach
///<para/> TreeViewItem
///</summary>
public sealed class TreeItemAttach
{
#region BringIntoView
///<summary>
/// DependencyProperty
///</summary>
public static readonly DependencyProperty BringIntoViewProperty = DependencyProperty.RegisterAttached("BringIntoView", typeof(bool), typeof(TreeItemAttach), new UIPropertyMetadata(false, (s, e) =>
{
if ((bool)e.NewValue != (bool)e.OldValue && s is TreeViewItem t)
{
if ((bool)e.NewValue)
{
t.Selected += BringIntoView;
}
else
{
t.Selected -= BringIntoView;
}
}
}));
///<summary>
/// Get
///</summary>
///<param name="target">DependencyObject</param>
///<returns>ICommand</returns>
public static bool GetBringIntoView(DependencyObject target)
{
return (bool)target.GetValue(BringIntoViewProperty);
}
///<summary>
/// Set
///</summary>
///<param name="target">DependencyObject</param>
///<param name="value">ICommand</param>
public static void SetBringIntoView(DependencyObject target, bool value)
{
target.SetValue(BringIntoViewProperty, value);
}
private static void BringIntoView(object sender, RoutedEventArgs e)
{
if (e.Source is TreeViewItem s)
{
double h = s.ActualHeight;
if (s.IsExpanded && s.Items.Count > 0)
{
h = s.ActualHeight / TreeWalker(s);
}
s.BringIntoView(new Rect(0, h * -1, s.ActualWidth, h * 2.5));
}
}
private static long TreeWalker(TreeViewItem item)
{
long c = item.Items.Count;
foreach (object i in item.Items)
{
if (i != null && item.ItemContainerGenerator.ContainerFromItem(i) is TreeViewItem t && t.IsExpanded && t.Items.Count > 0)
{
c += TreeWalker(t);
}
}
return c;
}
#endregion
}
}
它可用于像:
<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="tool:TreeItemAttach.BringIntoView" Value="True"/>
</Style>