Whenever a node is selected in my treeview, it automatically does a horizontal scroll to that item. Is there a way to disable this?
I had a similar problem. I needed to prevent horizontal scroll but preserve vertical scroll. My solution is to handle OnRequestBringIntoView method as I want it to behave. I created a ResourceDictionary for a TreeViewItem and added EventSetters for OnSelected and OnRequestBringIntoView methods.
MyResourceDictionary.xaml
MyResourceDictionary.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace Resources
{
partial class MyResourceDictionary:ResourceDictionary
{
public MyResourceDictionary()
{
InitializeComponent();
}
private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
e.Handled = true; //prevent event bubbling
var item = (TreeViewItem)sender;
TreeView tree = GetParentTree(item) as TreeView;
if(tree!=null)
{
var scrollViewer = tree.Template.FindName("_tv_scrollviewer_", tree) as ScrollViewer;
if (scrollViewer != null)
{
scrollViewer.ScrollToLeftEnd();//prevent horizontal scroll
Point relativePoint = item.TransformToAncestor(tree).Transform(new Point(0, 0));//get position of a selected item
if (relativePoint.Y <= scrollViewer.ContentVerticalOffset) return;//do no scroll if we select inside one 'scroll screen'
scrollViewer.ScrollToVerticalOffset(relativePoint.Y);//scroll to Y of a selected item
}
}
}
private DependencyObject GetParentTree(DependencyObject item)
{
var target = VisualTreeHelper.GetParent(item);
return target as TreeView != null ? target : GetParentTree(target);
}
private void OnSelected(object sender, RoutedEventArgs e) //handle programmatically selected items
{
var item = (TreeViewItem)sender;
item.BringIntoView();
e.Handled = true;
}
}
}