See the question and my original answer on StackOverflow

It's quite difficult to get the TreeViewItem for a given data item, in all cases, especially the virtualized ones.

Fortunately, Microsoft has provided a helper function for us here How to: Find a TreeViewItem in a TreeView that I have adapted so it doesn't need a custom VirtualizingStackPanel class (requires .NET Framework 4.5 or higher, for older versions, consult the link above).

Here is how you can replace your FocusTreeViewNode method:

private void FocusTreeViewNode(MenuItem node)
{
    if (node == null)
        return;

    var treeViewItem = GetTreeViewItem(tView, node);
    treeViewItem?.BringIntoView();
}


public static TreeViewItem GetTreeViewItem(ItemsControl container, object item)
{
    if (container == null)
        throw new ArgumentNullException(nameof(container));

    if (item == null)
        throw new ArgumentNullException(nameof(item));

    if (container.DataContext == item)
        return container as TreeViewItem;

    if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded)
    {
        container.SetValue(TreeViewItem.IsExpandedProperty, true);
    }

    container.ApplyTemplate();
    if (container.Template.FindName("ItemsHost", container) is ItemsPresenter itemsPresenter)
    {
        itemsPresenter.ApplyTemplate();
    }
    else
    {
        itemsPresenter = FindVisualChild<ItemsPresenter>(container);
        if (itemsPresenter == null)
        {
            container.UpdateLayout();
            itemsPresenter = FindVisualChild<ItemsPresenter>(container);
        }
    }

    var itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0);
    var children = itemsHostPanel.Children;
    var virtualizingPanel = itemsHostPanel as VirtualizingPanel;
    for (int i = 0, count = container.Items.Count; i < count; i++)
    {
        TreeViewItem subContainer;
        if (virtualizingPanel != null)
        {
            // this is the part that requires .NET 4.5+
            virtualizingPanel.BringIndexIntoViewPublic(i);
            subContainer = (TreeViewItem)container.ItemContainerGenerator.ContainerFromIndex(i);
        }
        else
        {
            subContainer = (TreeViewItem)container.ItemContainerGenerator.ContainerFromIndex(i);
            subContainer.BringIntoView();
        }

        if (subContainer != null)
        {
            TreeViewItem resultContainer = GetTreeViewItem(subContainer, item);
            if (resultContainer != null)
                return resultContainer;

            subContainer.IsExpanded = false;
        }
    }
    return null;
}

private static T FindVisualChild<T>(Visual visual) where T : Visual
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
    {
        if (VisualTreeHelper.GetChild(visual, i) is Visual child)
        {
            if (child is T item)
                return item;

            item = FindVisualChild<T>(child);
            if (item != null)
                return item;
        }
    }
    return null;
}