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

Add TabView SelectionPattern #2856

Merged
merged 9 commits into from
Jul 20, 2020

Conversation

marcelwgn
Copy link
Collaborator

Description

This PR adds the SelectionPattern to the TabViewAutomationPeer.
I am not using the internals ListView pattern since we plan to switch that out at some point, and then we would need to do all of that ourselves anyway.

Motivation and Context

Fixes #2847

How Has This Been Tested?

Add API test

Screenshots (if appropriate):

Open questions

Given that the TabView now has the SelectionPattern, should the TabViewItems also have the SelectionItemPattern?

There is also a way to run Accessibility Insights as a test through the Axe package. Maybe we could leverage that to prevent those errors in the future? Given that the MUXControlsTestApp is a bit special compared to a regular app, maybe this could be done with the XCG, after all it contains a lot of samples for the controls.
@stmoy FYI

@msft-github-bot msft-github-bot added the needs-triage Issue needs to be triaged by the area owners label Jul 7, 2020
@ranjeshj ranjeshj requested a review from teaP July 7, 2020 21:28
@ranjeshj ranjeshj added accessibility Narrator, keyboarding, UIA, etc area-TabView team-Controls Issue for the Controls team and removed needs-triage Issue needs to be triaged by the area owners labels Jul 7, 2020
@marcelwgn
Copy link
Collaborator Author

Implemented SelectionItem pattern on the TabViewItem now, added new API test for reading the IsSelected property and changing selection through the peer. Tested manually that changing selection also get's correctly announced in narrator.

@StephenLPeters
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@marcelwgn
Copy link
Collaborator Author

Looks like last test run failed due to heap limit. Merged with master to get latest fix for that.

@ranjeshj
Copy link
Contributor

ranjeshj commented Jul 8, 2020

Looks like last test run failed due to heap limit. Merged with master to get latest fix for that.

Could you please sync again? Keith made another fix.

@marcelwgn
Copy link
Collaborator Author

Could you please sync again? Keith made another fix.

Done,

@ranjeshj
Copy link
Contributor

ranjeshj commented Jul 8, 2020

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@marcelwgn
Copy link
Collaborator Author

Seems that CI failed due to visual tree verification files: https://dev.azure.com/ms/microsoft-ui-xaml/_build/results?buildId=93164&view=logs&j=f1f05f7d-9051-5031-1c4e-31dcdce6d081&t=dc1e8999-6150-522b-4887-86903abea868

Is this because of the recent renaming of the folder? Or is it more of a "general" issue? Also why are there new AppBarButton files? @kaiguo FYI


void TabViewItem::SetParentTabView(winrt::TabView const& tabView)
{
m_parentTabView = winrt::make_weak(tabView);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the fact that this is needed indicates that the components are architectured incorrectly. The TabViewItem shouldn't need to know about the Parent TabView. Instead I think that it might have been better to thave selection status held on the TabViewItem, which can raise Selection changed events that the TabView can use to manage the single selection. That being said I don't think we should change this now... maybe.

Copy link
Collaborator Author

@marcelwgn marcelwgn Jul 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really good point. The question that comes to my mind now, is why the NavigationViewItem has an IsSelected property, while the TabViewItem does not. Both act more or less like a tab item, in both cases only a single item can be selected at a time. Was/is there a specific reasoning why those two diverge here?

Maybe @stmoy has an idea?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TabViewItem does have an IsSelected property which is inherited from SelectorItem

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh missed that. The "Is selected" property doesn't appear in the official TabViewItem documentation. Also the TabViewItem/TabView do not care about that property at all.

Was this by design? I think @StephenLPeters is right here, that is something we should update. Currently only TabView knows about selection in contrast to NavigationView, where the items also know their selection status.

Copy link
Contributor

@Felix-Dev Felix-Dev Jul 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh missed that. The "Is selected" property doesn't appear in the official TabViewItem documentation. Also the TabViewItem/TabView do not care about that property at all.

@chingucoding The TabViewItem.IsSelected property does work though. See this XAML:

<muxc:TabView>
    <muxc:TabView.TabItems>
        <muxc:TabViewItem Header="Tab 1"/>
        <muxc:TabViewItem Header="Tab 2"/>
        <muxc:TabViewItem Header="Tab 3" IsSelected="True"/>
        <muxc:TabViewItem Header="Tab 4"/>
    </muxc:TabView.TabItems>
</muxc:TabView>

This gives me the expected result:
image

Copy link
Collaborator Author

@marcelwgn marcelwgn Jul 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since IsSelected works here, I removed the "GetParentTabView" pattern/code.

Edit: Readded it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chigy and @YuliKl for the documentation question

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chingucoding would it makes sense to move the pointer to the parent tab view onto the TabViewItemAutomationPeer since the TabViewItem itself doesn't need it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how would we set that property then? After all, we don't know when the AutomationPeer for a TabViewItem will be created, so TVI needs to "save" it until it will be needed. And since AutomationPeer are more or less "fire and forget" anyway (meaning they get created and can be used only once and get recreated for the next usage), the TVI AutomationPeer would always have to ask a TVI for it's parent TabView.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense


winrt::IRawElementProviderSimple TabViewItemAutomationPeer::SelectionContainer()
{
return nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to return the TabView's automation peer here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we need a reference to TabView here anyway?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. We need to either pass it down to the item or look up the tree from the item in this case. That said, I'm not exactly sure how Narrator uses this method though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the logic back, I added earlier in this PR. Walking up the tree seems a bit expensive here, though I am not a fan of having this relation between TabViewItem and TabView just for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YuliKl is there someone we can ask about how Narrator uses this?

Copy link

@LukaszMakar LukaszMakar Jul 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Narrator uses SelectionContainer for a few purposes:

  1. Listening to UIA events for the entire container.
  2. Understanding how selection behaves in the container and therefore which actions should be presented to the user. For instance, if the container is single selection + selection required, Narrator will not expose the action of removing an item from selection.
  3. Making announcements that inform the user about selection state of individual items. For instance, Narrator's "(non-)selected" for list items depends on whether the selection container supports multi-selection. Not quite your case but it does not mean it cannot become one.

Does that help?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think point 2 is a good reason here to not provide a nullptr for the SelectionContainer. After all TabView does not allow deselecting an item, and without the SelectionContainer being provided, Narrator wouldn't be able to hide that option from users.

Thank you for the information @LukaszMakar !

@StephenLPeters
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@StephenLPeters
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@StephenLPeters StephenLPeters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@StephenLPeters StephenLPeters merged commit 542e6f9 into microsoft:master Jul 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility Narrator, keyboarding, UIA, etc area-TabView team-Controls Issue for the Controls team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TabView appears to not be implementing the Selection pattern
6 participants