0
votes

I need to Scroll NavigationView to its SelectedItem. In which I tried below methods one with TryMoveFocusAsync and another by tring to get ScrollViewer through parent of the SelectedItem from SelectionChanged event. But, the parent seems to be null.

Note: NavigationView doesn't have ScrollIntoView like ListView

1st Method

   private async void OnSelectionChanged(
         NavigationView sender, NavigationViewSelectionChangedEventArgs args)
   {
        if (args.SelectedItem is NavigationViewItem item)
        {
           FocusManager.TryFocusAsync(
                    sender.SelectedItem as DependencyObject,
                    FocusState.Pointer);
           ViewModel.NavigateTo(item.Name);
         }
         UpdateBackButton();
   }

2nd Method

   private async void OnSelectionChanged(
        NavigationView sender, NavigationViewSelectionChangedEventArgs args)

(args.SelectedItem as NavigationViewItem).Parent returns null.

Is there a way to scroll the NavigationViewMenuItem to its selected index?

1

1 Answers

2
votes

Because the ScrollIntoView convenience method is not available outside of ListView it is a bit more work to get this done. First we need to write a helper method that finds the parent of a DependencyObject using the VisualTreeHelper:

private T FindParentOfType<T>(DependencyObject item)
{
    while (item != null)
    {
        item = VisualTreeHelper.GetParent(item);
        if (item is T expectedParent)
        {
            return expectedParent;
        }
    }
    return default;
}

Now using this, we first find the ScrollViewer (which should be a grand-parent of the NavigationViewItem):

var scrollViewer = FindParentOfType<ScrollViewer>(item);

We now need to find out the position of this menu item within the scroll viewer, which can be done using TransformToVisual and TransformPoint. Knowing this vertical location we can now scroll to it using ScrollViewer.ChangeView method:

if (scrollViewer != null)
{
    var transform = 
         item.TransformToVisual(scrollViewer)
             .TransformPoint(new Point(0,0));
    scrollViewer.ChangeView(null, transform.Y, null);
}