With this short post I’ll explain how to achieve a functionality similar to the one shown bellow.
The key to achieving this scenario is to use Behaviors.
Start off by adding a reference to the System.Windows.Interactivity.dll which is located in:
[WPF]
C:\Program Files (x86)\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\WPF\
[Silverlight]
C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\Silverlight\v4.0\Libraries\
(note: the location of the binary might be different on your machine)
Then create a class called AutoScrollBehavior.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.DragDrop;
#if SILVERLIGHT
using EventManager = Telerik.Windows.EventManager;
#endif namespace TreeView.AutoScroll
{
public class AutoScrollBehavior : Behavior<RadTreeView>
{
protected override void OnAttached()
{
base.OnAttached();
EventManager.RegisterClassHandler(typeof(ScrollViewer), RadDragAndDropManager.DropQueryEvent, new EventHandler<DragDropQueryEventArgs>(OnTreeViewScrollViewerDropQuery), true);
}
private static void OnTreeViewScrollViewerDropQuery(object sender, DragDropQueryEventArgs e)
{
var scrollViewer = sender as ScrollViewer;
if (scrollViewer != null)
{
var currentDragPoint = e.Options.CurrentDragPoint;
#if SILVERLIGHT
var generalTransform = scrollViewer.TransformToVisual(Application.Current.RootVisual);
#else
var generalTransform = scrollViewer.TransformToVisual(Window.GetWindow(scrollViewer));
#endif
var topLeft = generalTransform.Transform(new Point(0, 0));
var relative = new Point(currentDragPoint.X - topLeft.X, currentDragPoint.Y - topLeft.Y);
if (relative.Y > 0 && relative.Y < 40)
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - (20 * ((40 - relative.Y) / 40)));
}
if (relative.Y > scrollViewer.ActualHeight - 40 && relative.Y < scrollViewer.ActualHeight)
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + (20 * ((40 - (scrollViewer.ActualHeight - relative.Y)) / 40)));
}
if (relative.X > 0 && relative.X < 40)
{
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - (20 * ((40 - relative.X) / 40)));
}
if (relative.X > scrollViewer.ActualWidth - 40 && relative.X < scrollViewer.ActualWidth)
{
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + (20 * ((40 - (scrollViewer.ActualWidth - relative.X)) / 40)));
}
}
}
}
}
Finally, add this AutoScrollBehavior class to the TreeView.
<telerik:RadTreeView IsDragDropEnabled="True"> <i:Interaction.Behaviors> <local:AutoScrollBehavior /> </i:Interaction.Behaviors> </telerik:RadTreeView>
Where the “i” prefix stands for
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
By the end you should have a result similar to the one shown bellow.
Please find attached a sample solution containing both Silverlight and WPF project and…happy scrolling!
TreeView.AutoScroll.zip