Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NavView issue with SelectionChanged being raised upon displaymode change #1956

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
36 changes: 31 additions & 5 deletions dev/NavigationView/NavigationView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,12 @@ void NavigationView::CreateAndHookEventsToSettings(std::wstring_view settingsNam
bool shouldSelectSetting = selectedItem && IsSettingsItem(selectedItem);

if (shouldSelectSetting)
{
{
auto scopeGuard = gsl::finally([this]()
{
m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore = false;
});
m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore = true;
SetSelectedItemAndExpectItemInvokeWhenSelectionChangedIfNotInvokedFromAPI(nullptr);
}

Expand Down Expand Up @@ -806,7 +811,12 @@ void NavigationView::CreateAndHookEventsToSettings(std::wstring_view settingsNam
SetValue(s_SettingsItemProperty, settingsItem);

if (shouldSelectSetting)
{
{
auto scopeGuard = gsl::finally([this]()
{
m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore = false;
});
m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore = true;
SetSelectedItemAndExpectItemInvokeWhenSelectionChangedIfNotInvokedFromAPI(m_settingsItem.get());
}
}
Expand Down Expand Up @@ -1538,6 +1548,11 @@ void NavigationView::RaiseSelectionChangedEvent(winrt::IInspectable const& nextI
// If nextItem is selectionsuppressed, we should undo the selection. We didn't undo it OnSelectionChange because we want change by API has the same undo logic.
void NavigationView::ChangeSelection(const winrt::IInspectable& prevItem, const winrt::IInspectable& nextItem)
{
// Selection changed event was requested to be ignored by settings item restoration, so let's do that
if (m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore) {
return;
}

bool isSettingsItem = IsSettingsItem(nextItem);

if (IsSelectionSuppressed(nextItem))
Expand Down Expand Up @@ -2264,9 +2279,21 @@ void NavigationView::UpdateSingleSelectionFollowsFocusTemplateSetting()

void NavigationView::OnSelectedItemPropertyChanged(winrt::DependencyPropertyChangedEventArgs const& args)
{
auto newItem = args.NewValue();

ChangeSelection(args.OldValue(), newItem);
const auto newItem = args.NewValue();
const auto oldItem = args.OldValue();

ChangeSelection(oldItem, newItem);

// When we do not raise a "SelectItemChanged" event, the selection does not get animated.
// To prevent faulty visual states, we will animate that here
// Since we only do this for the settings item, check if the old item is our settings item
if (oldItem != newItem && m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore)
{
ChangeSelectStatusForItem(oldItem, false /*selected*/);
ChangeSelectStatusForItem(newItem, true /*selected*/);
AnimateSelectionChanged(oldItem, newItem);
}
marcelwgn marked this conversation as resolved.
Show resolved Hide resolved

if (m_appliedTemplate && IsTopNavigationView())
{
Expand Down Expand Up @@ -2306,7 +2333,6 @@ void NavigationView::SetSelectedItemAndExpectItemInvokeWhenSelectionChangedIfNot

m_indexOfLastSelectedItemInTopNav = m_topDataProvider.IndexOf(item); // for the next time we animate
}

SelectedItem(item);
}

Expand Down
3 changes: 2 additions & 1 deletion dev/NavigationView/NavigationView.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ class NavigationView :
// Customer select an item from SelectedItem property->ChangeSelection update ListView->LIstView raise OnSelectChange(we want stop here)->change property do do animation again.
// Customer clicked listview->listview raised OnSelectChange->SelectedItem property changed->ChangeSelection->Undo the selection by SelectedItem(prevItem) (we want it stop here)->ChangeSelection again ->...
bool m_shouldIgnoreNextSelectionChange{ false };

// Used to disable raising selection change iff settings item gets restored because of displaymode change
bool m_shouldIgnoreNextSelectionChangeBecauseSettingsRestore{ false };
// A flag to track that the selectionchange is caused by selection a item in topnav overflow menu
bool m_selectionChangeFromOverflowMenu{ false };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,41 @@ public void KeyboardFocusToolTipTest() // Verify tooltips appear when Keyboard f
}
}

[TestMethod]
[TestProperty("TestSuite", "C")]
public void DisplayModeChangeSelectionEventTest()
{
var testScenarios = RegressionTestScenario.BuildLeftNavRegressionTestScenarios();
foreach (var testScenario in testScenarios)
{
using (var setup = new TestSetupHelper(new[] { "NavigationView Tests", "NavigationView Test" }))
{
if (!PlatformConfiguration.IsOsVersionGreaterThanOrEqual(OSVersion.Redstone3))
{
Log.Warning("Test is disabled on RS2 and earlier because SplitView lacks the requisite events.");
return;
}
Button clearSelectedItem = new Button(FindElement.ById("ClearSelectionChangeIndicatorButton"));
TextBlock selectionRaisedIndicator = new TextBlock(FindElement.ById("SelectionChangedRaised"));

ComboBox selectedItem = new ComboBox(FindElement.ById("SelectedItemCombobox"));
selectedItem.SelectItemByName("Settings");
Verify.AreEqual("True", selectionRaisedIndicator.GetText());

ComboBox displayMode = new ComboBox(FindElement.ById("PaneDisplayModeCombobox"));
clearSelectedItem.InvokeAndWait();
displayMode.SelectItemByName("Top");
Verify.AreEqual("False", selectionRaisedIndicator.GetText());
Wait.ForIdle();


displayMode.SelectItemByName("Left");
Wait.ForIdle();
Verify.AreEqual("False", selectionRaisedIndicator.GetText());
}
}
}

[TestMethod]
[TestProperty("TestSuite", "C")]
public void PaneOpenCloseEventsTest()
Expand Down
3 changes: 3 additions & 0 deletions dev/NavigationView/TestUI/NavigationViewPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@
<ComboBoxItem Content="LeftCompact" Tag="LeftCompact"/>
<ComboBoxItem Content="LeftMinimal" Tag="LeftMinimal"/>
</ComboBox>
<Button x:Name="ClearSelectionChangeIndicatorButton" AutomationProperties.Name="ClearSelectionChangeIndicatorButton" Click="ClearSelectionChangeBlock">Clear selection changed indicator</Button>
<TextBlock VerticalAlignment="Center">Selection was raised: </TextBlock>
<TextBlock VerticalAlignment="Center" x:Name="SelectionChangedRaised" AutomationProperties.Name="SelectionChangedRaised"/>
</StackPanel>

<StackPanel Orientation="Horizontal">
Expand Down
6 changes: 6 additions & 0 deletions dev/NavigationView/TestUI/NavigationViewPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvoke

private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
SelectionChangedRaised.Text = "True";
// Reset argument type indicatiors
SelectionChangedItemType.Text = "null";
SelectionChangedItemContainerType.Text = "null";
Expand Down Expand Up @@ -380,6 +381,11 @@ private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelec
}
}

private void ClearSelectionChangeBlock(object sender,RoutedEventArgs e)
{
SelectionChangedRaised.Text = "False";
}

private void MoviesEnabledCheckbox_Checked(object sender, RoutedEventArgs e)
{
MoviesItem.IsEnabled = true;
Expand Down