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)) )); }
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); }
private static void UpdateImportantForAccessibilityForAddedChild(UIElement parent, DependencyObject child) { var parentPeer = FrameworkElementAutomationPeer.FromElement(parent); if (DoesHideDescendants(parent) || IsHiddenByAncestor(parentPeer)) { if (child is UIElement childElement) { // If an ancestor is "hiding" the element, set AccessibilityView to Raw. AutomationPeer childPeer = FrameworkElementAutomationPeer.FromElement(childElement); AutomationProperties.SetAccessibilityView(childElement, AccessibilityView.Raw); // Clear the generated label if any. if (IsInGenerativeStateAndHidden(childElement)) { childElement.ClearValue(AutomationProperties.NameProperty); } SetChildrenAccessibilityView(childPeer, AccessibilityView.Raw); } else { // If the parent or an ancestor is "hiding" the children, set AccessibilityView to Raw. SetChildrenAccessibilityView(parentPeer, AccessibilityView.Raw); } } }
/// <summary> /// When IsFullScreen is true, the content is displayed on top of the SplitView and the SplitView is /// not visible. Even as the user navigates (if possible) the SplitView remains hidden until /// IsFullScreen is set to false. /// </summary> /// <remarks> /// The original intent for this property was to allow the splash screen to be visible while the /// remaining content loaded duing app start. In Minimal (Shell), this is still used for this purpose, /// but many developers also leverage this property to view media full screen and similar use cases. /// </remarks> void UpdateFullScreen(bool?manual = null) { DebugWrite($"Manual: {manual}, IsFullScreen: {IsFullScreen}"); if ((manual ?? IsFullScreen) && !(popup?.IsOpen ?? false)) { this.Opacity = ShellSplitView.Opacity = HamburgerButton.Opacity = HamburgerBackground.Opacity = 0; ShellSplitView.IsHitTestVisible = ShellSplitView.IsEnabled = false; AutomationProperties.SetAccessibilityView(ShellSplitView, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Raw); ShellSplitView.Content = null; var frame = NavigationService?.Frame; if (popup == null) { var service = new PopupService(); popup = service.Open(PopupService.PopupSize.FullScreen, frame); } else { popup.Open(frame); } } else if (!(manual ?? IsFullScreen) && (popup?.IsOpen ?? false)) { this.Opacity = ShellSplitView.Opacity = HamburgerButton.Opacity = HamburgerBackground.Opacity = 1; ShellSplitView.IsHitTestVisible = ShellSplitView.IsEnabled = true; AutomationProperties.SetAccessibilityView(ShellSplitView, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Control); popup.Close(null); var frame = NavigationService?.Frame; ShellSplitView.Content = frame; } }
/// <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: AutomationProperties.SetAccessibilityView(element, AccessibilityView.Content); 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> /// When IsFullScreen is true, the content is displayed on top of the SplitView and the SplitView is /// not visible. Even as the user navigates (if possible) the SplitView remains hidden until /// IsFullScreen is set to false. /// </summary> /// <remarks> /// The original intent for this property was to allow the splash screen to be visible while the /// remaining content loaded duing app start. In Minimal (Shell), this is still used for this purpose, /// but many developers also leverage this property to view media full screen and similar use cases. /// </remarks> void UpdateFullScreen(bool?manual = null) { DebugWrite($"Manual: {manual}, IsFullScreen: {IsFullScreen}"); var frame = NavigationService?.Frame; if (manual ?? IsFullScreen) { HamburgerButton.Opacity = 0; ShellSplitView.IsHitTestVisible = ShellSplitView.IsEnabled = false; AutomationProperties.SetAccessibilityView(ShellSplitView, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Raw); ShellSplitView.Content = null; if (!RootGrid.Children.Contains(frame) && frame != null) { RootGrid.Children.Add(frame); } } else { HamburgerButton.Opacity = 1; ShellSplitView.IsHitTestVisible = ShellSplitView.IsEnabled = true; AutomationProperties.SetAccessibilityView(ShellSplitView, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Control); if (RootGrid.Children.Contains(frame) && frame != null) { RootGrid.Children.Remove(frame); } ShellSplitView.Content = frame; } }
private void CustomImagesTwo_Loaded(object sender, RoutedEventArgs e) { DependencyObject obj = FindVisualChildByName(CustomImagesTwo, "RatingBackgroundStackPanel"); var child = VisualTreeHelper.GetChild(obj, 0); AutomationProperties.SetAutomationId(child, "CustomImagesTwo_FirstImageItem"); AutomationProperties.SetAccessibilityView(child, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Control); CustomImagesTwoLoadedStageOneCheckBox.IsChecked = true; }
private void UpdateVisibility(bool notify = true, bool force = true) { var peer = FrameworkElementAutomationPeer.FromElement(this) as InfoBarAutomationPeer; if (!m_applyTemplateCalled) { // ApplyTemplate() hasn't been called yet but IsOpen has already been set. // Since this method will be called again shortly from ApplyTemplate, we'll just wait and send a notification then. m_notifyOpen = true; } else { // Don't do any work if nothing has changed (unless we are forcing a update) if (force || IsOpen != m_isVisible) { if (IsOpen) { if (notify && peer != null) { var notificationString = StringUtil.FormatString( ResourceAccessor.GetLocalizedStringResource(ResourceAccessor.SR_InfoBarOpenedNotification), ResourceAccessor.GetLocalizedStringResource(GetIconSeverityLevelResourceName(Severity)), Title, Message); peer.RaiseOpenedEvent(Severity, notificationString); } VisualStateManager.GoToState(this, "InfoBarVisible", false); AutomationProperties.SetAccessibilityView(this, AccessibilityView.Control); m_isVisible = true; } else { if (notify && peer != null) { var notificationString = ResourceAccessor.GetLocalizedStringResource(ResourceAccessor.SR_InfoBarClosedNotification); peer.RaiseClosedEvent(Severity, notificationString); } VisualStateManager.GoToState(this, "InfoBarCollapsed", false); AutomationProperties.SetAccessibilityView(this, AccessibilityView.Raw); m_isVisible = false; } } } }
public void OnTokensUpdatedPropertyChanged(bool oldValue, bool newValue) { if (m_expressionContainer != null && newValue) { m_expressionContainer.UpdateLayout(); m_expressionContainer.ChangeView(m_expressionContainer.ScrollableWidth, null, null, true); } var newIsAccessibilityViewControl = m_itemsControl != null && m_itemsControl.Items.Count > 0; if (m_isAccessibilityViewControl != newIsAccessibilityViewControl) { m_isAccessibilityViewControl = newIsAccessibilityViewControl; AutomationProperties.SetAccessibilityView(this, newIsAccessibilityViewControl ? AccessibilityView.Control : AccessibilityView.Raw); } UpdateScrollButtons(); }
/// <summary> /// Recursively sets AccessibilityView to <paramref name="accessibilityView"/> for <paramref name="parentPeer"/> children. /// </summary> /// <param name="parentPeer"></param> /// <param name="accessibilityView"></param> private static void SetChildrenAccessibilityView(AutomationPeer parentPeer, AccessibilityView accessibilityView) { if (parentPeer?.GetChildren() == null) { return; } foreach (AutomationPeer childPeer in parentPeer.GetChildren()) { UIElement child = GetUIElementFromAutomationPeer(childPeer); if (child != null) { AutomationProperties.SetAccessibilityView(child, accessibilityView); } SetChildrenAccessibilityView(childPeer, accessibilityView); } }
private void PersonPicture_Loaded(object sender, RoutedEventArgs e) { string InitialTextBlockName = "InitialsTextBlock"; TextBlock initialTextBlock = VisualTreeUtils.FindVisualChildByName(this.TestPersonPicture, InitialTextBlockName) as TextBlock; if (initialTextBlock != null) { AutomationProperties.SetName(initialTextBlock, InitialTextBlockName); AutomationProperties.SetAccessibilityView(initialTextBlock, AccessibilityView.Content); } string badgeTextBlockName = "BadgeNumberTextBlock"; TextBlock badgeTextBlock = VisualTreeUtils.FindVisualChildByName(this.TestPersonPicture, badgeTextBlockName) as TextBlock; if (badgeTextBlock != null) { AutomationProperties.SetName(badgeTextBlock, badgeTextBlockName); AutomationProperties.SetAccessibilityView(badgeTextBlock, AccessibilityView.Content); } string badgeGlyphIconName = "BadgeGlyphIcon"; FontIcon badgeFontIcon = VisualTreeUtils.FindVisualChildByName(this.TestPersonPicture, badgeGlyphIconName) as FontIcon; if (badgeFontIcon != null) { AutomationProperties.SetName(badgeFontIcon, badgeGlyphIconName); AutomationProperties.SetAccessibilityView(badgeFontIcon, AccessibilityView.Content); } string badgeEllipseName = "BadgingEllipse"; Ellipse badgeEllipse = VisualTreeUtils.FindVisualChildByName(this.TestPersonPicture, badgeEllipseName) as Ellipse; if (badgeEllipse != null) { AutomationProperties.SetName(badgeEllipse, badgeEllipseName); AutomationProperties.SetAccessibilityView(badgeEllipse, AccessibilityView.Content); } // Uno docs: This currently fails and returns null. // https://github.com/unoplatform/uno/issues/7258 //CollectionViewSource cvs = rootGrid.FindName("cvs") as CollectionViewSource; cvs.Source = GetGroupedPeople(); cvs.IsSourceGrouped = true; }
private void PersonPicture_Loaded(object sender, RoutedEventArgs e) { string InitialTextBlockName = "InitialsTextBlock"; TextBlock initialTextBlock = FindVisualChildByName(this.TestPersonPicture, InitialTextBlockName) as TextBlock; if (initialTextBlock != null) { AutomationProperties.SetName(initialTextBlock, InitialTextBlockName); AutomationProperties.SetAccessibilityView(initialTextBlock, AccessibilityView.Content); } string badgeTextBlockName = "BadgeNumberTextBlock"; TextBlock badgeTextBlock = FindVisualChildByName(this.TestPersonPicture, badgeTextBlockName) as TextBlock; if (badgeTextBlock != null) { AutomationProperties.SetName(badgeTextBlock, badgeTextBlockName); AutomationProperties.SetAccessibilityView(badgeTextBlock, AccessibilityView.Content); } string badgeGlyphIconName = "BadgeGlyphIcon"; FontIcon badgeFontIcon = FindVisualChildByName(this.TestPersonPicture, badgeGlyphIconName) as FontIcon; if (badgeFontIcon != null) { AutomationProperties.SetName(badgeFontIcon, badgeGlyphIconName); AutomationProperties.SetAccessibilityView(badgeFontIcon, AccessibilityView.Content); } string badgeEllipseName = "BadgingEllipse"; Ellipse badgeEllipse = FindVisualChildByName(this.TestPersonPicture, badgeEllipseName) as Ellipse; if (badgeEllipse != null) { AutomationProperties.SetName(badgeEllipse, badgeEllipseName); AutomationProperties.SetAccessibilityView(badgeEllipse, AccessibilityView.Content); } CollectionViewSource cvs = rootGrid.FindName("cvs") as CollectionViewSource; cvs.Source = GetGroupedPeople(); cvs.IsSourceGrouped = true; }
private static void UpdateImportantForAccessibilityForAddedChild(UIElement parent, DependencyObject child) { var parentPeer = FrameworkElementAutomationPeer.FromElement(parent); if (DoesHideDescendants(parent) || IsHiddenByAncestor(parentPeer)) { if (child is UIElement childElement) { // If an ancestor is "hiding" the element, set AccessibilityView to Raw. AutomationPeer childPeer = FrameworkElementAutomationPeer.FromElement(childElement); AutomationProperties.SetAccessibilityView(childElement, AccessibilityView.Raw); SetChildrenAccessibilityView(childPeer, AccessibilityView.Raw); } else { // If the parent or an ancestor is "hiding" the children, set AccessibilityView to Raw. SetChildrenAccessibilityView(parentPeer, AccessibilityView.Raw); } } }
private void ChangeCustomImagesTwoType_Click(object sender, RoutedEventArgs e) { if (CustomImagesTwo.ItemInfo is RatingItemImageInfo) { var rifi = new RatingItemFontInfo(); rifi.Glyph = "\uEB52"; rifi.UnsetGlyph = "\uEB52"; rifi.PointerOverGlyph = "\uEB52"; rifi.PointerOverPlaceholderGlyph = "\uEB52"; rifi.DisabledGlyph = "\uEB52"; CustomImagesTwo.ItemInfo = rifi; DependencyObject obj = FindVisualChildByName(CustomImagesTwo, "RatingBackgroundStackPanel"); var child = VisualTreeHelper.GetChild(obj, 0); AutomationProperties.SetAutomationId(child, "CustomImagesTwo_FirstTextItem"); AutomationProperties.SetAccessibilityView(child, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Control); CustomImagesTwoLoadedStageTwoCheckBox.IsChecked = true; } else { var imageInfo = new RatingItemImageInfo(); imageInfo.Image = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:/Assets/rating_set.png")); imageInfo.UnsetImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:/Assets/rating_unset.png"));; imageInfo.PlaceholderImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:/Assets/rating_placeholder.png"));; imageInfo.DisabledImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:/Assets/rating_disabled.png"));; imageInfo.PointerOverImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:/Assets/rating_mouseoverset.png"));; imageInfo.PointerOverPlaceholderImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:/Assets/rating_mouseoverplaceholder.png")); CustomImagesTwo.ItemInfo = imageInfo; DependencyObject obj = FindVisualChildByName(CustomImagesTwo, "RatingBackgroundStackPanel"); var child = VisualTreeHelper.GetChild(obj, 0); AutomationProperties.SetAutomationId(child, "CustomImagesTwo_FirstImageItem_Again"); AutomationProperties.SetAccessibilityView(child, Windows.UI.Xaml.Automation.Peers.AccessibilityView.Control); CustomImagesTwoLoadedStageThreeCheckBox.IsChecked = true; } }
/// <summary> /// Recursively sets AccessibilityView to <paramref name="accessibilityView"/> for <paramref name="parentPeer"/> children. /// </summary> /// <param name="parentPeer"></param> /// <param name="accessibilityView"></param> private static void SetChildrenAccessibilityView(AutomationPeer parentPeer, AccessibilityView accessibilityView) { if (parentPeer?.GetChildren() == null) { return; } foreach (AutomationPeer childPeer in parentPeer.GetChildren()) { UIElement child = GetUIElementFromAutomationPeer(childPeer); if (child != null) { AutomationProperties.SetAccessibilityView(child, accessibilityView); // If element is hidden clear the generated label if any. if (IsInGenerativeStateAndHidden(child)) { child.ClearValue(AutomationProperties.NameProperty); } } SetChildrenAccessibilityView(childPeer, accessibilityView); } }
protected override Size ArrangeOverride(Size finalSize) { if (Children.Count == 0) { return(finalSize); } float posX = 0; var lastChild = Children[Children.Count - 1]; float lastChildWidth = 0; if (Children.Count > 2 && ShouldPrioritizeLastItem()) { lastChildWidth = (float)lastChild.DesiredSize.Width; } foreach (var item in Children) { var widthAvailable = finalSize.Width - posX; if (item != lastChild) { widthAvailable -= lastChildWidth; } float itemWidth = (float)item.DesiredSize.Width; if (widthAvailable > 0 && itemWidth <= widthAvailable) { // stack the items horizontally (left to right) item.Arrange(new Rect(posX, 0, itemWidth, finalSize.Height)); AutomationProperties.SetAccessibilityView(item, AccessibilityView.Content); posX += (float)item.RenderSize.Width; } else { // Not display the item item.Arrange(new Rect(0, 0, 0, 0)); AutomationProperties.SetAccessibilityView(item, AccessibilityView.Raw); } } return(finalSize); }
/// <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> /// Sets AccessibilityView and Name property for <paramref name="element"/> and its children according to /// the element's "importantForAccessibility" property (if <paramref name="hideNodes"/> is false) / "Raw" (if <paramref name="hideNodes"/> is true) , /// and "accessibilityLabel". /// </summary> /// <param name="element"></param> /// <param name="elementPeer"></param> /// <param name="hideNodes"></param> private static void UpdateAccessibilityViewAndNameForUIElement(UIElement element, AutomationPeer elementPeer, bool hideNodes) { var importantForAccessibilityProp = GetImportantForAccessibilityProp(element); var accessibilityLabelProp = GetAccessibilityLabelProp(element); var hasLabelSet = !string.IsNullOrEmpty(accessibilityLabelProp); #if PERF_LOG s_treeContext.Value.ProcessedNodesCount++; #endif // // Phase 1: set correct AV for the current node if (hideNodes) { AutomationProperties.SetAccessibilityView(element, AccessibilityView.Raw); } else { switch (importantForAccessibilityProp) { case ImportantForAccessibility.Auto when !hasLabelSet: element.ClearValue(AutomationProperties.AccessibilityViewProperty); break; case ImportantForAccessibility.Auto when hasLabelSet: case ImportantForAccessibility.Yes: AutomationProperties.SetAccessibilityView(element, AccessibilityView.Content); break; case ImportantForAccessibility.No: case ImportantForAccessibility.NoHideDescendants: AutomationProperties.SetAccessibilityView(element, AccessibilityView.Raw); break; default: throw new NotImplementedException("Can't reach here"); } } // // Phase 2: go down the tree after deciding how // We can follow dirty nodes (may be none) or traverse all // We can switch to "hiding nodes", to "unhiding nodes", or not switch at all. bool willHideChildren = hideNodes || importantForAccessibilityProp == ImportantForAccessibility.Yes || importantForAccessibilityProp == ImportantForAccessibility.NoHideDescendants || importantForAccessibilityProp == ImportantForAccessibility.Auto && hasLabelSet; bool traverseAllChildren; if (willHideChildren) { // Will be hiding children // Force a full traversal of children if current node hasn't been hiding them (or not sure), // else just follow the "dirty" nodes, if any traverseAllChildren = GetCurrentlyHidingChildren(element) != ElementAccessibilityContext.HidingChildren.Yes; SetChildrenAccessibilityViewAndNameForPeer(elementPeer, true, traverseAllChildren); } else { // Will be unhiding children // Force a full traversal of children if current node has been hiding them (or not sure), // else just follow the "dirty" nodes, if any traverseAllChildren = GetCurrentlyHidingChildren(element) != ElementAccessibilityContext.HidingChildren.No; SetChildrenAccessibilityViewAndNameForPeer(elementPeer, false, traverseAllChildren); } SetCurrentlyHidingChildren(element, willHideChildren ? ElementAccessibilityContext.HidingChildren.Yes : ElementAccessibilityContext.HidingChildren.No); // // Phase 3: set name if needed (all children nodes have been updated by this point) if (traverseAllChildren || GetDirty(element)) { if (importantForAccessibilityProp == ImportantForAccessibility.Yes && !hasLabelSet) { // Set generated name SetName(element, GenerateNameFromPeer(elementPeer)); } else { // Set name as the specified label (includes null as a special case) SetName(element, accessibilityLabelProp); } } }