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

NavigationView not updating UIA users about changed selection and expand state #2692

Merged
27 changes: 22 additions & 5 deletions dev/NavigationView/NavigationView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,12 @@ void NavigationView::OnNavigationViewItemInvoked(const winrt::NavigationViewItem
if (updateSelection)
{
auto ip = GetIndexPathForContainer(nvi);

// Determine if we will update collapse/expand which will happen on iff the item has children
marcelwgn marked this conversation as resolved.
Show resolved Hide resolved
if (DoesNavigationViewItemHaveChildren(nvi))
{
m_shouldIgnoreUIASelectionRaiseAsExpandCollapseWillRaise = true;
}
UpdateSelectionModelSelection(ip);
}

Expand Down Expand Up @@ -1930,13 +1936,24 @@ void NavigationView::ChangeSelection(const winrt::IInspectable& prevItem, const
UnselectPrevItem(prevItem, nextItem);
ChangeSelectStatusForItem(nextItem, true /*selected*/);

if (winrt::AutomationPeer peer = winrt::FrameworkElementAutomationPeer::FromElement(*this))
// Selection changed and we need to notify UIA
// HOWEVER expand collapse can also trigger if an item can expand/collapse
// There are multiple cases when selectino changes:
marcelwgn marked this conversation as resolved.
Show resolved Hide resolved
// - Through click on item with no children -> No expand/collapse change
// - Through click on item with children -> Expand/collapse change
// - Through API with item without children -> No expand/collapse change
// - Through API with item with children -> No expand/collapse change
if (!m_shouldIgnoreUIASelectionRaiseAsExpandCollapseWillRaise)
{
auto navViewItemPeer = peer.as<winrt::NavigationViewAutomationPeer>();
winrt::get_self<NavigationViewAutomationPeer>(navViewItemPeer)->RaiseSelectionChangedEvent(
prevItem, nextItem
);
if (winrt::AutomationPeer peer = winrt::FrameworkElementAutomationPeer::FromElement(*this))
{
auto navViewItemPeer = peer.as<winrt::NavigationViewAutomationPeer>();
winrt::get_self<NavigationViewAutomationPeer>(navViewItemPeer)->RaiseSelectionChangedEvent(
prevItem, nextItem
);
}
}
m_shouldIgnoreUIASelectionRaiseAsExpandCollapseWillRaise = false;
marcelwgn marked this conversation as resolved.
Show resolved Hide resolved

RaiseSelectionChangedEvent(nextItem, isSettingsItem, recommendedDirection);
AnimateSelectionChanged(nextItem);
Expand Down
2 changes: 2 additions & 0 deletions dev/NavigationView/NavigationView.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,5 +441,7 @@ class NavigationView :
bool m_isOpenPaneForInteraction{ false };

bool m_moveTopNavOverflowItemOnFlyoutClose{ false };

bool m_shouldIgnoreUIASelectionRaiseAsExpandCollapseWillRaise{ false };
};

18 changes: 10 additions & 8 deletions dev/NavigationView/NavigationViewAutomationPeer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ void NavigationViewAutomationPeer::RaiseSelectionChangedEvent(winrt::IInspectabl
{
if (winrt::AutomationPeer::ListenerExists(winrt::AutomationEvents::SelectionPatternOnInvalidated))
{
//RaiseAutomationEvent(winrt::AutomationEvents::SelectionPatternOnInvalidated);
//RaiseAutomationEvent(winrt::AutomationEvents::SelectionItemPatternOnElementSelected);

// box_value(oldState) doesn't work here, use ReferenceWithABIRuntimeClassName to make Narrator can unbox it.
//RaisePropertyChangedEvent(winrt::SelectionPatternIdentifiers::SelectionProperty(),
// box_value(oldSelection),
// box_value(newSelecttion)
//);
if (auto nv = Owner().try_as<winrt::NavigationView>())
{
if (auto nvi = winrt::get_self<NavigationView>(nv)->GetSelectedContainer())
{
if (auto peer = winrt::FrameworkElementAutomationPeer::CreatePeerForElement(nvi))
{
peer.RaiseAutomationEvent(winrt::AutomationEvents::SelectionItemPatternOnElementSelected);
}
}
}
}
}