From 0a380bc1127490800f22343dc7ba23be015f52ef Mon Sep 17 00:00:00 2001 From: Yimeng Wu Date: Sat, 12 Sep 2020 04:53:38 +0800 Subject: [PATCH] NavigationView: Fix IsPaneOpen=false ignored on launch when pane is launched in Left expanded state (microsoft/microsoft-ui-xaml#3197) --- .../NavigationView/NavigationView.cs | 17 +- .../ApiTests/NavigationViewTests.cs | 169 +++++++++++++++++- 2 files changed, 175 insertions(+), 11 deletions(-) diff --git a/ModernWpf.Controls/NavigationView/NavigationView.cs b/ModernWpf.Controls/NavigationView/NavigationView.cs index e45b7a29..5b83e1f1 100644 --- a/ModernWpf.Controls/NavigationView/NavigationView.cs +++ b/ModernWpf.Controls/NavigationView/NavigationView.cs @@ -4118,12 +4118,17 @@ void OnIsPaneOpenChanged() { if (m_rootSplitView is { } splitView) { - // splitview.IsPaneOpen and nav.IsPaneOpen is two way binding. There is possible change that SplitView.IsPaneOpen=false, then - // nav.IsPaneOpen=false. We don't need to set force flag in this situation - if (splitView.IsPaneOpen) - { - m_wasForceClosed = true; - } + // splitview.IsPaneOpen and nav.IsPaneOpen is two way binding. If nav.IsPaneOpen=false and splitView.IsPaneOpen=true, + // then the pane has been closed by API and we treat it as a forced close. + // If, however, splitView.IsPaneOpen=false, then nav.IsPaneOpen is just following the SplitView here and the pane + // was closed, for example, due to app window resizing. We don't set the force flag in this situation. + m_wasForceClosed = splitView.IsPaneOpen; + } + else + { + // If there is no SplitView (for example it hasn't been loaded yet) then nav.IsPaneOpen was set directly + // so we treat it as a closed force. + m_wasForceClosed = true; } } diff --git a/test/ModernWpfTestApp/ApiTests/NavigationViewTests.cs b/test/ModernWpfTestApp/ApiTests/NavigationViewTests.cs index 1003e906..e9c5149c 100644 --- a/test/ModernWpfTestApp/ApiTests/NavigationViewTests.cs +++ b/test/ModernWpfTestApp/ApiTests/NavigationViewTests.cs @@ -64,7 +64,6 @@ private NavigationView SetupNavigationView(NavigationViewPaneDisplayMode paneDis return navView; } - private NavigationView SetupNavigationViewScrolling(NavigationViewPaneDisplayMode paneDisplayMode = NavigationViewPaneDisplayMode.Auto) { NavigationView navView = null; @@ -281,6 +280,166 @@ public void VerifyPaneDisplayModeChangingPaneAccordingly() } } + [TestMethod] + public void VerifyPaneDisplayModeAndIsPaneOpenInterplayOnNavViewLaunch() + { + Log.Comment("--- PaneDisplayMode: LeftMinimal ---"); + VerifyForPaneDisplayModeLeftMinimal(); + + Log.Comment("--- PaneDisplayMode: LeftCompact ---"); + VerifyForPaneDisplayModeLeftCompact(); + + Log.Comment("--- PaneDisplayMode: Left ---"); + VerifyForPaneDisplayModeLeft(); + + Log.Comment("--- PaneDisplayMode: Auto ---"); + VerifyForPaneDisplayModeAuto(); + + void VerifyForPaneDisplayModeLeftMinimal() + { + Log.Comment("Verify pane is closed when IsPaneOpen=true"); + var navView = SetupNavView(NavigationViewPaneDisplayMode.LeftMinimal, true); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + + Log.Comment("Verify pane is closed when IsPaneOpen=false"); + navView = SetupNavView(NavigationViewPaneDisplayMode.LeftMinimal, false); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + } + + void VerifyForPaneDisplayModeLeftCompact() + { + Log.Comment("Verify pane is closed when IsPaneOpen=true"); + var navView = SetupNavView(NavigationViewPaneDisplayMode.LeftCompact, true); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + + Log.Comment("Verify pane is closed when IsPaneOpen=false"); + navView = SetupNavView(NavigationViewPaneDisplayMode.LeftCompact, false); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + } + + void VerifyForPaneDisplayModeLeft() + { + Log.Comment("Verify pane is open when IsPaneOpen=true"); + var navView = SetupNavView(NavigationViewPaneDisplayMode.Left, true); + + RunOnUIThread.Execute(() => + { + Verify.IsTrue(navView.IsPaneOpen, "NavigationView pane should have been open"); + }); + + Log.Comment("Verify pane is closed when IsPaneOpen=false"); + navView = SetupNavView(NavigationViewPaneDisplayMode.Left, false); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + } + + void VerifyForPaneDisplayModeAuto() + { + Log.Comment("Verify pane is closed when launched in minimal state and IsPaneOpen=true"); + var navView = SetupNavView(NavigationViewPaneDisplayMode.Auto, true, NavigationViewDisplayMode.Minimal); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + + Log.Comment("Verify pane is closed when launched in compact state and IsPaneOpen=true"); + navView = SetupNavView(NavigationViewPaneDisplayMode.Auto, true, NavigationViewDisplayMode.Compact); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + + Log.Comment("Verify pane is open when launched in expanded state and IsPaneOpen=true"); + navView = SetupNavView(NavigationViewPaneDisplayMode.Auto, true, NavigationViewDisplayMode.Expanded); + + RunOnUIThread.Execute(() => + { + Verify.IsTrue(navView.IsPaneOpen, "NavigationView pane should have been open"); + }); + + Log.Comment("Verify pane is closed when launched in minimal state and IsPaneOpen=false"); + navView = SetupNavView(NavigationViewPaneDisplayMode.Auto, false, NavigationViewDisplayMode.Minimal); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + + Log.Comment("Verify pane is closed when launched in compact state and IsPaneOpen=false"); + navView = SetupNavView(NavigationViewPaneDisplayMode.Auto, false, NavigationViewDisplayMode.Compact); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + + Log.Comment("Verify pane is closed when launched in expanded state and IsPaneOpen=false"); + navView = SetupNavView(NavigationViewPaneDisplayMode.Auto, false, NavigationViewDisplayMode.Expanded); + + RunOnUIThread.Execute(() => + { + Verify.IsFalse(navView.IsPaneOpen, "NavigationView pane should have been closed"); + }); + } + + NavigationView SetupNavView(NavigationViewPaneDisplayMode paneDisplayMode, bool isPaneOpen, NavigationViewDisplayMode displayMode = NavigationViewDisplayMode.Expanded) + { + NavigationView navView = null; + RunOnUIThread.Execute(() => + { + navView = new NavigationView(); + navView.MenuItems.Add(new NavigationViewItem() { Content = "MenuItem" }); + + navView.PaneDisplayMode = paneDisplayMode; + navView.IsPaneOpen = isPaneOpen; + navView.ExpandedModeThresholdWidth = 600.0; + navView.CompactModeThresholdWidth = 400.0; + + if (paneDisplayMode == NavigationViewPaneDisplayMode.Auto) + { + switch (displayMode) + { + case NavigationViewDisplayMode.Minimal: + navView.Width = navView.CompactModeThresholdWidth - 10.0; + break; + case NavigationViewDisplayMode.Compact: + navView.Width = navView.ExpandedModeThresholdWidth - 10.0; + break; + case NavigationViewDisplayMode.Expanded: + navView.Width = navView.ExpandedModeThresholdWidth + 10.0; + break; + } + } + + Content = navView; + }); + + IdleSynchronizer.Wait(); + return navView; + } + } + [TestMethod] public void VerifyDefaultsAndBasicSetting() { @@ -648,16 +807,16 @@ public void VerifyCanNotAddWUXItems() [TestMethod] public void VerifyVerifyHeaderContentMarginOnTopNav() { - VerifyVerifyHeaderContentMargin(NavigationViewPaneDisplayMode.Top, "VerifyVerifyHeaderContentMarginOnTopNav"); + VerifyHeaderContentMargin(NavigationViewPaneDisplayMode.Top, "VerifyVerifyHeaderContentMarginOnTopNav"); } [TestMethod] - public void VerifyVerifyHeaderContentMarginOnMinimalNav() + public void VerifyHeaderContentMarginOnMinimalNav() { - VerifyVerifyHeaderContentMargin(NavigationViewPaneDisplayMode.LeftMinimal, "VerifyVerifyHeaderContentMarginOnMinimalNav"); + VerifyHeaderContentMargin(NavigationViewPaneDisplayMode.LeftMinimal, "VerifyVerifyHeaderContentMarginOnMinimalNav"); } - private void VerifyVerifyHeaderContentMargin(NavigationViewPaneDisplayMode paneDisplayMode, string masterFilePrefix) + private void VerifyHeaderContentMargin(NavigationViewPaneDisplayMode paneDisplayMode, string masterFilePrefix) { UIElement headerContent = null;