NavigationView: refresh closed compact state when a reused NavigationViewItem is loaded in a new host

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ec9a38b2-2629-4a10-bfb5-552decfe6848
This commit is contained in:
ayushjai19andCopilot committed 2026-10-20 17:13:01 +05:30
1 parent 540eb5dcd2
commit 0499ee2077
1 file changed
+13 -6
@@ -42,6 +42,10 @@ NavigationViewItem::NavigationViewItem()
{
SetDefaultStyleKey(this);
SetValue(s_MenuItemsProperty, winrt::make<Vector<winrt::IInspectable>>());
// Items outside a NavigationView-owned repeater are only prepared on load (see OnLoaded), and they can be
// moved to a different host later (for example from MenuItems to PaneFooter or Content).
Loaded({ this, &NavigationViewItem::OnLoaded });
}
void NavigationViewItem::UpdateVisualStateNoTransition()
@@ -101,12 +105,6 @@ void NavigationViewItem::OnApplyTemplate()
{
PrepNavigationViewItem(splitView);
}
else
{
// If the NVI is not prepared in an ItemPresenter, it will not have reference to SplitView. So check OnLoaded
// if it the reference has been manually set in NavigationViewItemBase::OnLoaded().
Loaded({ this, &NavigationViewItem::OnLoaded });
}
if (HasPotentialChildren())
{
@@ -175,6 +173,15 @@ void NavigationViewItem::LoadMenuItemsHost()
void NavigationViewItem::OnLoaded(winrt::IInspectable const&, winrt::RoutedEventArgs const&)
{
// Items in a NavigationView-owned repeater are prepared in OnApplyTemplate and refreshed by the repeater.
if (IsInNavigationViewOwnedRepeater() && m_splitViewIsPaneOpenChangedRevoker)
{
return;
}
// If the NVI is not prepared in an ItemPresenter, it will not have reference to SplitView, so it is prepared here once
// NavigationViewItemBase::OnLoaded() has set the NavigationView. This also runs again when the item is loaded in a new host,
// so the closed compact state is recomputed for that host. Re-preparing replaces the SplitView subscriptions.
if (auto splitView = GetSplitView())
{
PrepNavigationViewItem(splitView);