3

I am currently working on an wpf application where I have a treeview with a hierarchichal datatemplate with my own object "Workstep".

What I want to do:

I want to hit a specific key (letter) and bring the first workstep with the a name starting with that letter on top of my treeview

Why:

Because the treeview is large and scrolling until the specific letter takes a lot of time in the production area of the company i am working for

My work until now: In my viewmodel I catch the keydown event of my treeview with the following method (watch out-> the "K" is just a example letter to show what I mean):

Public Sub TreeViewKeyDown(sender as Object, e as KeyEventArgs)
   if e IsNot Nothing AndAlso e.Key = Key.K Then
      For Each w In myTree
         If w.Name.StartsWith("K") Then
           Dim treeViewItem As TreeViewItem = CType(m_TreeViewInstance.ItemContainerGenerator.ContainerFromItem(w), TreeViewItem)
         treeViewItem.BringIntoView()  
         End If
      Next
   End If

The problem with my current solution is that my items come to view but are not on top of my treeview, as I would like to have.

Does anybody have a clue how to do that?

(btw: Didn't get the answer through this article: Treeview -- How to scroll until selected item is on top?)

ouflak
  • 2,408
  • 10
  • 40
  • 47
kbax
  • 63
  • 1
  • 8

1 Answers1

1

I achieve this in the following way:

    var scrollviewer = FindVisualChild<ScrollViewer>(treeview);                        
    if (scrollviewer != null) scrollviewer.ScrollToEnd();
    treeviewitem.BringIntoView();

Including FindVisualChild for completeness:

    private static T FindVisualChild<T>(Visual visual) where T : Visual
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
        {
            Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
            if (child != null)
            {
                T correctlyTyped = child as T;
                if (correctlyTyped != null) return correctlyTyped;
                T descendent = FindVisualChild<T>(child);
                if (descendent != null) return descendent;                    
            }
        }
        return null;
    }

Just to add, I do this without virtualization as I prefer to take the hit when I first load the treeview. I used this method on a treeview with over one thousand items without noticing any delay in the UI.