Exemple #1
0
 private string GetSimpleAccessibilityName()
 {
     if (FeatureConfiguration.AutomationPeer.UseSimpleAccessibility &&
         Owner is View view &&
         AutomationProperties.GetAccessibilityView(Owner) != AccessibilityView.Raw)
     {
         /// We get our name by aggregating the name of all our children.
         /// See <see cref="FeatureConfiguration.AutomationPeer.UseSimpleAccessibility" /> for details.
         return(string.Join(", ", view
                            .EnumerateAllChildren()
                            .OfType <IFrameworkElement>()
                            .Where(child => child.Visibility == Visibility.Visible)
                            .Select(child =>
         {
             // We set this for two reasons:
             // - We want to disable accessibility focus for elements whose names are aggregated into the name of their parent.
             // - We want to prevent these elements from enumerating their own children in GetSimpleAccessibilityName(),
             //	 which might be called as a result of calling automationPeer.GetName() below.
             AutomationProperties.SetAccessibilityView(child, AccessibilityView.Raw);
             return child;
         })
                            .Select(FromIFrameworkElement)
                            .Where(automationPeer => automationPeer != null)
                            .Select(automationPeer => automationPeer.GetName())
                            .Where(childName => !string.IsNullOrEmpty(childName))
                            ));
     }
        /// <summary>
        /// Updates name on <paramref name="element"/> from <see cref="AccessibilityLabelAttachedProperty"/>
        /// or from generation, and then updates all parents' generated names where update is due.
        /// </summary>
        /// <param name="element"></param>
        private static void UpdateName(UIElement element)
        {
            // Update name on the element itself from AccessibilityLabel or name generation.
            var peer = FrameworkElementAutomationPeer.FromElement(element);

            if (IsInGenerativeState(element))
            {
                if (AutomationProperties.GetAccessibilityView(element) != AccessibilityView.Raw)
                {
                    var generatedName = GenerateNameFromUpdated(peer);
                    AutomationProperties.SetName(element, generatedName);
                }
            }
            else
            {
                var accessibilityLabel = GetAccessibilityLabelAttached(element);
                if (string.IsNullOrEmpty(accessibilityLabel))
                {
                    element.ClearValue(AutomationProperties.NameProperty);
                }
                else
                {
                    AutomationProperties.SetName(element, accessibilityLabel);
                }
            }

            // Update generated names only starting from parent and up.
            var parentPeer = peer.Navigate(AutomationNavigationDirection.Parent) as AutomationPeer;

            if (parentPeer != null)
            {
                UpdateGeneratedNameHereAndUp(parentPeer);
            }
        }
Exemple #3
0
        public ImplicitTextBlock(DependencyObject parent)
        {
            // Propagate the parent's (ContentPresenter or ContentControl) AutomationProperties.AccessibilityView to ImplicitTextBlock once.
            var accessibilityView = AutomationProperties.GetAccessibilityView(parent);

            AutomationProperties.SetAccessibilityView(this, accessibilityView);
        }
        internal override void OnInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)
        {
            if (!AutomationConfiguration.IsAccessibilityEnabled)
            {
                return;
            }

            var isAccessible = AutomationProperties.GetAccessibilityView(Owner) != AccessibilityView.Raw;

            if (isAccessible)
            {
                // TODO: Set View.Focusable and View.FocusableInTouchMode to true to ensure SendAccessibilityEvent gets called?
                info.Focusable          = isAccessible;
                info.ContentDescription = GetName();
                info.Password           = IsPassword();
                info.Enabled            = IsEnabled();

                // TODO: Use GetAutomationControlType() and GetPattern() instead
                info.Clickable     = GetClickable();
                info.Checked       = GetChecked();
                info.Checkable     = GetCheckable();
                info.Editable      = GetEditable();
                info.InputType     = GetInputType();
                info.MultiLine     = GetMultiline();
                info.Selected      = GetSelected();
                info.MaxTextLength = GetMaxTextLength();
                info.Scrollable    = GetScrollable();
            }
        }
Exemple #5
0
        public void VerifyAccessibilityView()
        {
            RunOnUIThread.Execute(() =>
            {
                var progressRing      = new ProgressRing();
                progressRing.IsActive = true;

                Verify.AreNotEqual(AccessibilityView.Raw, AutomationProperties.GetAccessibilityView(progressRing));

                progressRing.IsActive = false;
                Verify.AreEqual(AccessibilityView.Raw, AutomationProperties.GetAccessibilityView(progressRing));
            });
        }
        /// <summary>
        /// Update <see cref="AutomationProperties.NameProperty"/> on <paramref name="peer"/>'s owner
        /// and all its parents as far up as needed and only when the name is generated. This must be called
        /// when anything influencing generated names has changed in <paramref name="peer"/>'s owner or somewhere in its subtree.
        /// </summary>
        /// <param name="peer"></param>
        private static void UpdateGeneratedNameHereAndUp(AutomationPeer peer)
        {
            var current = peer;

            while (current != null)
            {
                UIElement element = GetUIElementFromAutomationPeer(current);
                if (IsElementIgnoresChildrenForName(element))
                {
                    break;
                }
                if (IsInGenerativeState(element) &&
                    (AutomationProperties.GetAccessibilityView(element) != AccessibilityView.Raw))
                {
                    var generatedName = GenerateNameFromUpdated(current);
                    AutomationProperties.SetName(element, generatedName);
                }
                current = current.Navigate(AutomationNavigationDirection.Parent) as AutomationPeer;
            }
        }
        internal override bool UpdateAccessibilityElement()
        {
            if (!AutomationConfiguration.IsAccessibilityEnabled)
            {
                return(false);
            }

            var isAccessible = AutomationProperties.GetAccessibilityView(Owner) != AccessibilityView.Raw;

            if (isAccessible && Owner is UIView view)
            {
                view.AccessibilityLabel  = GetName();
                view.AccessibilityTraits = GetAccessibilityTraits();

                // TODO
                //view.AccessibilityHint
                //view.AccessibilityValue
                //view.AccessibilityElementsHidden
                //view.AccessibilityNavigationStyle
            }

            return(isAccessible);
        }
        /// <summary>
        /// Sets AccessibilityView property for <paramref name="element"/> and its children according to
        /// the element's <paramref name="importantForAccessibility"/> property and
        /// <see cref="AccessibilityLabelAttachedProperty"/> values.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="elementPeer"></param>
        /// <param name="importantForAccessibility"></param>
        private static void UpdateAccessibilityViewForUIElement(UIElement element, AutomationPeer elementPeer, ImportantForAccessibility importantForAccessibility)
        {
            switch (importantForAccessibility)
            {
            case ImportantForAccessibility.Auto when GetAccessibilityLabelAttached(element) == null:
                element.ClearValue(AutomationProperties.AccessibilityViewProperty);

                SetChildrenAccessibilityViewFromImportantForAccessibility(elementPeer);
                break;

            case ImportantForAccessibility.Auto when GetAccessibilityLabelAttached(element) != null:
            case ImportantForAccessibility.Yes:
                var currentAccessibilityView = AutomationProperties.GetAccessibilityView(element);

                AutomationProperties.SetAccessibilityView(element, AccessibilityView.Content);
                // Generate the label in case the element was hidden.
                if (currentAccessibilityView == AccessibilityView.Raw)
                {
                    UpdateName(element);
                }
                SetChildrenAccessibilityView(elementPeer, AccessibilityView.Raw);
                break;

            case ImportantForAccessibility.No:
                AutomationProperties.SetAccessibilityView(element, AccessibilityView.Raw);
                SetChildrenAccessibilityViewFromImportantForAccessibility(elementPeer);
                break;

            case ImportantForAccessibility.NoHideDescendants:
                AutomationProperties.SetAccessibilityView(element, AccessibilityView.Raw);
                SetChildrenAccessibilityView(elementPeer, AccessibilityView.Raw);
                break;

            default:
                break;
            }
        }
 /// <summary>
 /// True if the <paramref name="element"/> generates name, but it is not visible to narrator.
 /// </summary>
 /// <param name="element"></param>
 /// <returns></returns>
 private static bool IsInGenerativeStateAndHidden(UIElement element) => AutomationProperties.GetAccessibilityView(element) == AccessibilityView.Raw && IsInGenerativeState(element);
 protected override bool IsControlElementCore() => AutomationProperties.GetAccessibilityView(Owner) >= AccessibilityView.Control;
        public void ExpanderAutomationPeerTest()
        {
            RunOnUIThread.Execute(() =>
            {
                var root = (StackPanel)XamlReader.Load(
                    @"<StackPanel xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 
                             xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
                             xmlns:primitives='using:Microsoft.UI.Xaml.Controls.Primitives'
                             xmlns:controls='using:Microsoft.UI.Xaml.Controls'> 
                             <controls:Expander x:Name ='ExpandedExpander' AutomationProperties.Name='ExpandedExpander' IsExpanded='True' Margin='12' HorizontalAlignment='Left'>
                                <controls:Expander.Header>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition />
                                            <ColumnDefinition Width='80'/>
                                        </Grid.ColumnDefinitions>
                                        <StackPanel Margin='0,14,0,16'>
                                            <TextBlock AutomationProperties.Name='test' Text='This expander is expanded by default.'  Margin='0,0,0,4' />
                                            <TextBlock Text='This is the second line of text.' />
                                        </StackPanel>
                                        <ToggleSwitch Grid.Column='1'/>
                                    </Grid>
                                </controls:Expander.Header>
                                <Button AutomationProperties.AutomationId = 'ExpandedExpanderContent'> Content </Button>
                             </controls:Expander>
                                    </StackPanel>");

                Content = root;
                Content.UpdateLayout();

                var expander = VisualTreeHelper.GetChild(root, 0) as Expander;

                expander.IsExpanded = true;
                Content.UpdateLayout();

                var grid             = VisualTreeHelper.GetChild(expander, 0);
                var toggleButton     = VisualTreeHelper.GetChild(grid, 0);
                var toggleButtonGrid = VisualTreeHelper.GetChild(toggleButton, 0);
                var contentPresenter = VisualTreeHelper.GetChild(toggleButtonGrid, 0);
                var grid2            = VisualTreeHelper.GetChild(contentPresenter, 0);
                var stackPanel       = VisualTreeHelper.GetChild(grid2, 0);
                var textBlock1       = VisualTreeHelper.GetChild(stackPanel, 0) as TextBlock;
                var textBlock2       = VisualTreeHelper.GetChild(stackPanel, 1) as TextBlock;
                var toggleSwitch     = VisualTreeHelper.GetChild(grid2, 1) as ToggleSwitch;

                var border = VisualTreeHelper.GetChild(grid, 1);
                var expanderContentBorder           = VisualTreeHelper.GetChild(border, 0);
                var expanderContentContentPresenter = VisualTreeHelper.GetChild(expanderContentBorder, 0);
                var button = VisualTreeHelper.GetChild(expanderContentContentPresenter, 0) as Button;

                Verify.AreEqual("ExpandedExpander", AutomationProperties.GetName(expander));

                // Verify ExpandedExpander header content are included in the accessibility tree
                Verify.AreEqual(AutomationProperties.GetAccessibilityView(textBlock1), AccessibilityView.Content);
                Verify.AreEqual(AutomationProperties.GetAccessibilityView(textBlock2), AccessibilityView.Content);
                Verify.AreEqual(AutomationProperties.GetAccessibilityView(toggleSwitch), AccessibilityView.Content);

                // Verify ExpandedExpander content is included in the accessibility tree
                Verify.AreEqual(AutomationProperties.GetAccessibilityView(button), AccessibilityView.Content);

                expander.IsExpanded = false;
                Content.UpdateLayout();

                // Verify ExpandedExpander content is not included in the accessibility tree and not readable once collapsed
                Verify.AreNotEqual(AutomationProperties.GetAccessibilityView(button), AccessibilityView.Raw);
            });
        }