public List <NSObject> GetAccessibilityElements()
        {
            if (Container == null || Element == null)
            {
                return(null);
            }

            var children = Element.Descendants();
            SortedDictionary <int, List <VisualElement> > tabIndexes = null;
            List <NSObject> views = new List <NSObject>();

            foreach (var child in children)
            {
                if (!(child is VisualElement ve))
                {
                    continue;
                }

                tabIndexes = ve.GetSortedTabIndexesOnParentPage(out _);
                break;
            }

            if (tabIndexes == null)
            {
                return(null);
            }

            foreach (var idx in tabIndexes?.Keys)
            {
                var tabGroup = tabIndexes[idx];
                foreach (var child in tabGroup)
                {
                    if (child is Layout ||
                        !(
                            child is VisualElement ve && ve.IsTabStop &&
                            AutomationProperties.GetIsInAccessibleTree(ve) != false &&                             // accessible == true
                            ve.GetRenderer().NativeView is ITabStop tabStop)
                        )
                    {
                        continue;
                    }

                    var thisControl = tabStop.TabStop;

                    if (thisControl == null)
                    {
                        continue;
                    }

                    if (views.Contains(thisControl))
                    {
                        break;                         // we've looped to the beginning
                    }
                    views.Add(thisControl);
                }
            }

            return(views);
        }
        protected virtual void UpdateNativeWidget()
        {
            UpdateEnabled();
            UpdateTabStop();
            UpdateTabIndex();
            UpdateAutomationId();
            var isInAccessibleTree = AutomationProperties.GetIsInAccessibleTree(Element);

            if (!(isInAccessibleTree.HasValue && !isInAccessibleTree.Value))
            {
                UpdateAutomationLabeledBy();
                UpdateAutomationName();
                UpdateAutomationHelpText();
            }
        }
Example #3
0
        void IOrderedTraversalController.UpdateTraversalOrder()
        {
            // traversal order wasn't added until API 22
            if ((int)Forms.SdkInt < 22)
            {
                return;
            }

            // since getting and updating the traversal order is expensive, let's only do it when a screen reader is active
            // note that this does NOT get auto updated when you enable TalkBack, so the page will need to be reloaded to enable this path
            var am = AccessibilityManager.FromContext(Context);

            if (!am.IsEnabled)
            {
                return;
            }

            SortedDictionary <int, List <ITabStopElement> > tabIndexes = null;

            foreach (var child in Element.LogicalChildren)
            {
                if (!(child is VisualElement ve))
                {
                    continue;
                }

                tabIndexes = ve.GetSortedTabIndexesOnParentPage(out _);
                break;
            }

            if (tabIndexes == null)
            {
                return;
            }

            AView prevControl = null;

            foreach (var idx in tabIndexes?.Keys)
            {
                var tabGroup = tabIndexes[idx];
                foreach (var child in tabGroup)
                {
                    if (child is Layout ||
                        !(
                            child is VisualElement ve && ve.IsTabStop &&
                            AutomationProperties.GetIsInAccessibleTree(ve) != false &&                             // accessible == true
                            ve.GetRenderer()?.View is ITabStop tabStop)
                        )
                    {
                        continue;
                    }

                    var thisControl = tabStop.TabStop;

                    if (thisControl == null)
                    {
                        continue;
                    }

                    // this element should be the first thing focused after the root
                    if (prevControl == null)
                    {
                        thisControl.AccessibilityTraversalAfter = NoId;
                    }
                    else
                    {
                        if (thisControl != prevControl)
                        {
                            thisControl.AccessibilityTraversalAfter = prevControl.Id;
                        }
                    }

                    prevControl = thisControl;
                }
            }
        }