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!