Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1777,7 +1777,6 @@ void OpenPane()
// Call this when you want an uncancellable close
void ClosePane()
{
CollapseMenuItemsInRepeater(m_leftNavRepeater);
try
{
m_isOpenPaneForInteraction = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public override void OnApplyTemplate()
{
// Stop UpdateVisualState before template is applied. Otherwise the visuals may be unexpected
m_appliedTemplate = false;
m_restoreToExpandedState = false;

UnhookEventsAndClearFields();

Expand Down Expand Up @@ -203,6 +204,7 @@ void OnSplitViewPropertyChanged(DependencyObject sender, DependencyProperty args
{
UpdateIsClosedCompact();
ReparentRepeater();
HandleExpansionStateMemory();
}
}

Expand Down Expand Up @@ -237,6 +239,25 @@ internal void UpdateIsClosedCompact()
}
}

private void HandleExpansionStateMemory()
{
if (IsTopLevelItem)
{
var splitView = GetSplitView();
if (splitView != null)
{
if (splitView.IsPaneOpen)
{
RestoreExpandedState();
}
else
{
ForceCollapse();
}
}
}
}

void UpdateNavigationViewItemToolTip()
{
var toolTipContent = ToolTipService.GetToolTip(this);
Expand Down Expand Up @@ -283,6 +304,8 @@ void SuggestedToolTipChanged(object newContent)

void OnIsExpandedPropertyChanged(DependencyPropertyChangedEventArgs args)
{
m_restoreToExpandedState = false;

if (FrameworkElementAutomationPeer.FromElement(this) is AutomationPeer peer)
{
var navViewItemPeer = (NavigationViewItemAutomationPeer)peer;
Expand All @@ -292,6 +315,8 @@ void OnIsExpandedPropertyChanged(DependencyPropertyChangedEventArgs args)
ExpandCollapseState.Collapsed
);
}

Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This UpdateVisualState(true) call at the end of OnIsExpandedPropertyChanged should have a comment explaining why it's necessary here, as the visual state update may not be obvious from the context of handling expansion state changes.

Suggested change
// Update the visual state to reflect the change in expansion state.

Copilot uses AI. Check for mistakes.
UpdateVisualState(true);
}

void OnIconPropertyChanged(DependencyPropertyChangedEventArgs args)
Expand Down Expand Up @@ -342,7 +367,7 @@ void UpdateVisualStateForInfoBadge()
{
if (m_navigationViewItemPresenter is { } presenter)
{
var stateName = ShouldShowInfoBadge() ? "InfoBadgeVisible" : "InfoBadgeCollapsed";
var stateName = ShouldShowInfoBadge() ? "InfoBadgeVisible" : "InfoBadgeCollapsed";
VisualStateManager.GoToState(presenter, stateName, false /*useTransitions*/);
}
}
Expand Down Expand Up @@ -370,6 +395,8 @@ void UpdateVisualStateForNavigationViewPositionChange()
break;
case NavigationViewRepeaterPosition.TopPrimary:
case NavigationViewRepeaterPosition.TopFooter:
m_restoreToExpandedState = false;

Comment on lines +398 to +399
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The m_restoreToExpandedState = false assignments in the switch statement for TopPrimary, TopFooter, and TopOverflow cases lack explanation. A comment should clarify why restoration of expansion state should be disabled for top navigation positions.

Copilot uses AI. Check for mistakes.
if (SharedHelpers.IsRS4OrHigher() && false /*Application.Current.FocusVisualKind == FocusVisualKind.Reveal*/)
{
stateName = c_OnTopNavigationPrimaryReveal;
Expand All @@ -381,6 +408,7 @@ void UpdateVisualStateForNavigationViewPositionChange()
break;
case NavigationViewRepeaterPosition.TopOverflow:
stateName = c_OnTopNavigationOverflow;
m_restoreToExpandedState = false;
break;
}

Expand Down Expand Up @@ -629,6 +657,24 @@ internal void ShowHideChildren()
}
}

void ForceCollapse()
{
if (IsExpanded)
{
IsExpanded = false;
m_restoreToExpandedState = true;
}
}

void RestoreExpandedState()
{
if (m_restoreToExpandedState)
{
IsExpanded = true;
m_restoreToExpandedState = false;
}
}

void ReparentRepeater()
{
if (HasChildren())
Expand Down Expand Up @@ -966,5 +1012,9 @@ void UnhookEventsAndClearFields()
bool m_isPointerOver = false;

bool m_isRepeaterParentedToFlyout = false;

// NavigationView needs to force collapse top level items when the pane closes.
// This bool is used to remember which items need to be restored to expanded state when the pane is opened again.
bool m_restoreToExpandedState = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public override void OnApplyTemplate()
{
m_expandCollapseChevron = expandCollapseChevron;
InputHelper.SetIsTapEnabled(expandCollapseChevron, true);
InputHelper.SetStopRouting(expandCollapseChevron, true);
InputHelper.AddTappedHandler(expandCollapseChevron, navigationViewItem.OnExpandCollapseChevronTapped);
}
navigationViewItem.UpdateVisualStateNoTransition();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
IsTitleBarAutoPaddingEnabled="False"
Loaded="OnNavigationViewControlLoaded"
PaneClosing="NavigationViewControl_PaneClosing"
PaneDisplayMode="Auto"
PaneDisplayMode="Left"
PaneOpening="NavigationViewControl_PaneOpening"
SelectionChanged="OnNavigationViewSelectionChanged"
IsSettingsVisible="True">
Expand Down
37 changes: 37 additions & 0 deletions source/iNKORE.UI.WPF.Modern/Input/InputHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,45 @@ private static void RaiseTapped(UIElement element, int timestamp)

#endregion

#region StopRouting
public static readonly DependencyProperty StopRoutingProperty =
DependencyProperty.RegisterAttached(
"StopRouting",
typeof(bool),
typeof(InputHelper),
new PropertyMetadata(false));

public static bool GetStopRouting(UIElement element)
{
return (bool)element.GetValue(StopRoutingProperty);
}

public static void SetStopRouting(UIElement element, bool value)
{
if (value)
{
element.SetValue(StopRoutingProperty, value);
}
else
{
element.ClearValue(StopRoutingProperty);
}
}
#endregion

private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var element = (UIElement)sender;

if (!GetIsPressed(element))
{
SetIsPressed(element, true);

if (GetStopRouting(element))
{
element.CaptureMouse();
e.Handled = true;
}
}
}

Expand All @@ -122,6 +154,11 @@ private static void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
SetIsPressed((UIElement)sender, false);

if (GetStopRouting(element))
{
element.ReleaseMouseCapture();
}

var lastArgs = _lastTappedArgs;

if (lastArgs != null && lastArgs.Handled && lastArgs.Timestamp == e.Timestamp)
Expand Down
Loading