With this short post I’ll explain how to achieve a functionality similar to the one shown bellow.


Unable to display content. Adobe Flash is required.

 

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.

 

Unable to display content. Adobe Flash is required.

 

Please find attached a sample solution containing both Silverlight and WPF project and…happy scrolling!

TreeView.AutoScroll.zip


About the Author

Hristo Milyakov

 is Software Developer in Telerik XAML Team

Comments

Comments are disabled in preview mode.