diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs index f938961e..669800bd 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs @@ -1777,7 +1777,6 @@ void OpenPane() // Call this when you want an uncancellable close void ClosePane() { - CollapseMenuItemsInRepeater(m_leftNavRepeater); try { m_isOpenPaneForInteraction = true; diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItem.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItem.cs index 715c4ad3..025aa0bf 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItem.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItem.cs @@ -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(); @@ -203,6 +204,7 @@ void OnSplitViewPropertyChanged(DependencyObject sender, DependencyProperty args { UpdateIsClosedCompact(); ReparentRepeater(); + HandleExpansionStateMemory(); } } @@ -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); @@ -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; @@ -292,6 +315,8 @@ void OnIsExpandedPropertyChanged(DependencyPropertyChangedEventArgs args) ExpandCollapseState.Collapsed ); } + + UpdateVisualState(true); } void OnIconPropertyChanged(DependencyPropertyChangedEventArgs args) @@ -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*/); } } @@ -370,6 +395,8 @@ void UpdateVisualStateForNavigationViewPositionChange() break; case NavigationViewRepeaterPosition.TopPrimary: case NavigationViewRepeaterPosition.TopFooter: + m_restoreToExpandedState = false; + if (SharedHelpers.IsRS4OrHigher() && false /*Application.Current.FocusVisualKind == FocusVisualKind.Reveal*/) { stateName = c_OnTopNavigationPrimaryReveal; @@ -381,6 +408,7 @@ void UpdateVisualStateForNavigationViewPositionChange() break; case NavigationViewRepeaterPosition.TopOverflow: stateName = c_OnTopNavigationOverflow; + m_restoreToExpandedState = false; break; } @@ -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()) @@ -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; } } diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItemPresenter.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItemPresenter.cs index e766a2a4..937a7fca 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItemPresenter.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationViewItemPresenter.cs @@ -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(); diff --git a/source/iNKORE.UI.WPF.Modern.Gallery/Navigation/NavigationRootPage.xaml b/source/iNKORE.UI.WPF.Modern.Gallery/Navigation/NavigationRootPage.xaml index 5a7bbd50..50c1a1f3 100644 --- a/source/iNKORE.UI.WPF.Modern.Gallery/Navigation/NavigationRootPage.xaml +++ b/source/iNKORE.UI.WPF.Modern.Gallery/Navigation/NavigationRootPage.xaml @@ -81,7 +81,7 @@ IsTitleBarAutoPaddingEnabled="False" Loaded="OnNavigationViewControlLoaded" PaneClosing="NavigationViewControl_PaneClosing" - PaneDisplayMode="Auto" + PaneDisplayMode="Left" PaneOpening="NavigationViewControl_PaneOpening" SelectionChanged="OnNavigationViewSelectionChanged" IsSettingsVisible="True"> diff --git a/source/iNKORE.UI.WPF.Modern/Input/InputHelper.cs b/source/iNKORE.UI.WPF.Modern/Input/InputHelper.cs index ab07900b..b74c093a 100644 --- a/source/iNKORE.UI.WPF.Modern/Input/InputHelper.cs +++ b/source/iNKORE.UI.WPF.Modern/Input/InputHelper.cs @@ -104,6 +104,25 @@ 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) + { + element.SetValue(StopRoutingProperty, value); + } + #endregion + private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var element = (UIElement)sender; @@ -111,6 +130,12 @@ private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) if (!GetIsPressed(element)) { SetIsPressed(element, true); + + if (GetStopRouting(element)) + { + element.CaptureMouse(); + e.Handled = true; + } } } @@ -122,6 +147,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)