Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

[Bug] Default TabIndex inconsistency on UWP #12433

Closed
johnshardman opened this issue Oct 9, 2020 · 3 comments
Closed

[Bug] Default TabIndex inconsistency on UWP #12433

johnshardman opened this issue Oct 9, 2020 · 3 comments

Comments

@johnshardman
Copy link

Description

The VisualElement.TabIndex property has a default value of 0, as per the code in VisualElement.cs shown here:

	public static readonly BindableProperty TabIndexProperty =
		BindableProperty.Create(nameof(TabIndex),
								typeof(int),
								typeof(VisualElement),
								defaultValue: 0,
								propertyChanged: OnTabIndexPropertyChanged,
								defaultValueCreator: TabIndexDefaultValueCreator);

However, on UWP, Control.TabIndex has a default value of Int32.MaxValue, as per the documentation at https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.control.tabindex

Either the Xamarin.Forms.VisualElement.TabIndexProperty needs its default value changed to match UWP, or the VisualElementRenderer (and potentially other renderers) need to convert the Xamarin.Forms default value to the UWP default value.

Basic Information

  • Version with issue: 4.8
@johnshardman johnshardman added s/unverified New report that has yet to be verified t/bug 🐛 labels Oct 9, 2020
@johnshardman
Copy link
Author

To confirm this, try the following code on UWP, pushing an instance of TestWebViewTabIndexPageView onto the NavigationStack.

using Xamarin.Forms;

using System.Threading.Tasks;

namespace ViewsUsingXamarinForms
{
public class TestWebViewTabIndexPageView : ContentPage
{
private bool _firstTimeOnAppearing = true;

    public TestWebViewTabIndexPageView()
    {
        PopulatePage();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (_firstTimeOnAppearing)
        {
            _firstTimeOnAppearing = false;

            //PopulatePage();

            // The following is just here as a convenience.
            // It's a nasty, hacky way of setting the initial focus, 
            // that introduces a race condition. Good enough for
            // this repro sample though.
            Task.Run(async () =>
            {
                await Task.Delay(1000);
                Xamarin.Essentials.MainThread.BeginInvokeOnMainThread(() =>
                {
                    if (_button1 != null)
                        _button1.Focus();
                });
            });
        }
    }

    private Button _button1;
    private Button _button2;
    private WebView _webView;

    private void PopulatePage()
    {
        int defaultTabIndex = int.MaxValue; // UWP says this should be the max int. Xamarin.Forms docs say it should be 0;

        _button1 = new Button
        {
            Text = "Button 1 (should be first in tab order)",
            TextColor = Color.Black,
            BackgroundColor = Color.White,
            TabIndex = defaultTabIndex,
            VerticalOptions = LayoutOptions.Start
        };

        _webView = new WebView
        {
            BackgroundColor = Color.White,
            HorizontalOptions = LayoutOptions.Fill,
            TabIndex = defaultTabIndex,
            VerticalOptions = LayoutOptions.FillAndExpand,
            Source = new HtmlWebViewSource
            {
                Html = "<html><body>Hello (should be second in tab order)<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29</body></html>"
            }
        };

        _button2 = new Button
        {
            Text = "Button 2 (should be third in tab order)",
            TextColor = Color.Black,
            BackgroundColor = Color.White,
            TabIndex = defaultTabIndex,
            VerticalOptions = LayoutOptions.End
        };

        Content = new StackLayout
        {
            HorizontalOptions = LayoutOptions.Fill,
            VerticalOptions = LayoutOptions.Fill,
            BackgroundColor = Color.Pink,
            Children =
            {
                _button1,
                _webView,
                _button2
            }
        };
    }
}

}

With defaultTabIndex set to int.MaxValue, the tab order is as expected (Button, WebView, Button) as per the UWP documentation. If, however, defaultTabIndex is set to 0 (which is what the Xamarin documentation says is the default), the tab order becomes (Button, Button, WebView), which is not what would be expected.

@StephaneDelcroix StephaneDelcroix added p/UWP a/a11y 🔍 and removed s/unverified New report that has yet to be verified labels Oct 19, 2020
@samhouts
Copy link
Contributor

That's interesting. We followed the UWP documentation when designing this feature, which clearly says that TabIndex of 0 means elements will be added in order of XAML declaration or child collection. #2789 https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/keyboard-accessibility

@rachelkang
Copy link
Contributor

Hi, @johnshardman - I'm closing this issue for the same reason I commented on your other issue at #12456 (comment)

We no longer advise that TabIndex be used and hope you will have better results with using SemanticOrderView from the XamarinCommunityToolkit, which has already proven to be a more accessible alternative. That being said, if you continue to have any issues, please feel free to reopen this issue!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants