From c50eb272618029df10f42bf7566a8eac5d77785a Mon Sep 17 00:00:00 2001 From: Keith Mahoney <41657372+kmahone@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:12:57 -0700 Subject: [PATCH] Fix issue where NavView IsPaneOpen can end up incorrect when layout changes (#8695) --- dev/NavigationView/NavigationView.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/dev/NavigationView/NavigationView.cpp b/dev/NavigationView/NavigationView.cpp index 55912b304f..7c5e9af6bc 100644 --- a/dev/NavigationView/NavigationView.cpp +++ b/dev/NavigationView/NavigationView.cpp @@ -4294,21 +4294,30 @@ void NavigationView::UpdatePaneDisplayMode(winrt::NavigationViewPaneDisplayMode // See #1702 and #1787 if (!IsTopNavigationView()) { - if (IsPaneOpen()) + // In rare cases it is possible to end up in a state where two calls to OnPropertyChanged for PaneDisplayMode can end up on the stack + // Calls above to UpdatePaneDisplayMode() can result in further property updates. + // As a result of this reentrancy, we can end up with an incorrect result for IsPaneOpen as the later OnPropertyChanged for PaneDisplayMode + // will complete during the OnPropertyChanged of the earlier one. + // To avoid this, we only call OpenPane()/ClosePane() if PaneDisplayMode has not changed. + if (newDisplayMode == PaneDisplayMode()) { - if (newDisplayMode == winrt::NavigationViewPaneDisplayMode::LeftMinimal) + if (IsPaneOpen()) { - ClosePane(); + if (newDisplayMode == winrt::NavigationViewPaneDisplayMode::LeftMinimal) + { + ClosePane(); + } } - } - else - { - if (oldDisplayMode == winrt::NavigationViewPaneDisplayMode::LeftMinimal - && newDisplayMode == winrt::NavigationViewPaneDisplayMode::Left) + else { - OpenPane(); + if (oldDisplayMode == winrt::NavigationViewPaneDisplayMode::LeftMinimal + && newDisplayMode == winrt::NavigationViewPaneDisplayMode::Left) + { + OpenPane(); + } } } + } }