From 2165d04dff8696da3d35396fe8a3a6a0e64d493a Mon Sep 17 00:00:00 2001 From: Bastian Schmidt Date: Wed, 2 Aug 2023 18:05:47 +0200 Subject: [PATCH] Fixes #1125 (finally) --- Changelog.md | 6 ++++ Fluent.Ribbon.Showcase/TestContent.xaml | 2 ++ ...RibbonBackstageTabControlAutomationPeer.cs | 21 +++++++++++ .../Peers/RibbonTabControlAutomationPeer.cs | 35 +++++++++++++++---- Fluent.Ribbon/Controls/BackstageTabControl.cs | 4 +++ .../Extensions/UIElementExtensions.cs | 13 +++++++ .../Themes/Controls/BackstageTabControl.xaml | 2 +- 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 Fluent.Ribbon/Extensions/UIElementExtensions.cs diff --git a/Changelog.md b/Changelog.md index 544e8027f..66d197a06 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,11 @@ # Changelog for Fluent.Ribbon +## 10.0.2 + +- ### Bug fixes + + - [#1125](../../issues/1125) - BackStage Back Button doesn't have an accessibility text. + ## 10.0.1 - ### Bug fixes diff --git a/Fluent.Ribbon.Showcase/TestContent.xaml b/Fluent.Ribbon.Showcase/TestContent.xaml index 29b7f64da..6d066e36d 100644 --- a/Fluent.Ribbon.Showcase/TestContent.xaml +++ b/Fluent.Ribbon.Showcase/TestContent.xaml @@ -177,6 +177,7 @@ @@ -317,6 +318,7 @@ /// Automation peer for . @@ -34,4 +37,22 @@ protected override ItemAutomationPeer CreateItemAutomationPeer(object item) bool ISelectionProvider.IsSelectionRequired => true; bool ISelectionProvider.CanSelectMultiple => false; + + /// + protected override List GetChildrenCore() + { + var baseResult = base.GetChildrenCore() ?? new List(); + + if (this.OwningBackstageTabControl.BackButton is { } backButton) + { + var backButtonAutomationPeer = backButton.GetOrCreateAutomationPeer(); + + if (backButtonAutomationPeer is not null) + { + baseResult.Insert(0, backButtonAutomationPeer); + } + } + + return baseResult; + } } \ No newline at end of file diff --git a/Fluent.Ribbon/Automation/Peers/RibbonTabControlAutomationPeer.cs b/Fluent.Ribbon/Automation/Peers/RibbonTabControlAutomationPeer.cs index 669810b61..3e28e8b0d 100644 --- a/Fluent.Ribbon/Automation/Peers/RibbonTabControlAutomationPeer.cs +++ b/Fluent.Ribbon/Automation/Peers/RibbonTabControlAutomationPeer.cs @@ -1,9 +1,12 @@ namespace Fluent.Automation.Peers; using System.Collections.Generic; +using System.Linq; using System.Windows; using System.Windows.Automation.Peers; using System.Windows.Automation.Provider; +using Fluent.Extensions; +using Fluent.Internal; /// /// Automation peer for . @@ -81,9 +84,29 @@ protected override List GetChildrenCore() { var children = base.GetChildrenCore() ?? new List(); - var toolbarPanel = this.OwningRibbonTabControl.ToolbarPanel; + if (this.OwningRibbonTabControl.Menu is { } menu) + { + var automationPeer = menu.GetOrCreateAutomationPeer(); + + if (automationPeer is null) + { + var child = UIHelper.GetVisualChildren(menu) + .OfType() + .FirstOrDefault(x => x.IsVisible); + + if (child is not null) + { + automationPeer = child.GetOrCreateAutomationPeer(); + } + } - if (toolbarPanel is not null) + if (automationPeer is not null) + { + children.Insert(0, automationPeer); + } + } + + if (this.OwningRibbonTabControl.ToolbarPanel is { } toolbarPanel) { foreach (UIElement? child in toolbarPanel.Children) { @@ -92,7 +115,7 @@ protected override List GetChildrenCore() continue; } - var automationPeer = CreatePeerForElement(child); + var automationPeer = child.GetOrCreateAutomationPeer(); if (automationPeer is not null) { @@ -101,11 +124,9 @@ protected override List GetChildrenCore() } } - var displayOptionsButton = this.OwningRibbonTabControl.DisplayOptionsControl; - - if (displayOptionsButton is not null) + if (this.OwningRibbonTabControl.DisplayOptionsControl is { } displayOptionsButton) { - var automationPeer = CreatePeerForElement(displayOptionsButton); + var automationPeer = displayOptionsButton.GetOrCreateAutomationPeer(); if (automationPeer is not null) { diff --git a/Fluent.Ribbon/Controls/BackstageTabControl.cs b/Fluent.Ribbon/Controls/BackstageTabControl.cs index 7c5bcb71a..ebc608ae4 100644 --- a/Fluent.Ribbon/Controls/BackstageTabControl.cs +++ b/Fluent.Ribbon/Controls/BackstageTabControl.cs @@ -21,6 +21,7 @@ namespace Fluent; /// [TemplatePart(Name = "PART_SelectedContentHost", Type = typeof(ContentPresenter))] [TemplatePart(Name = "PART_ItemsPanelContainer", Type = typeof(UIElement))] +[TemplatePart(Name = "PART_BackButton", Type = typeof(UIElement))] public class BackstageTabControl : Selector, ILogicalChildSupport { #region Properties @@ -29,6 +30,8 @@ public class BackstageTabControl : Selector, ILogicalChildSupport internal UIElement? ItemsPanelContainer { get; private set; } + internal UIElement? BackButton { get; private set; } + /// Identifies the dependency property. public static readonly DependencyProperty BackButtonUidProperty = DependencyProperty.Register( nameof(BackButtonUid), typeof(string), typeof(BackstageTabControl), new PropertyMetadata(default(string))); @@ -329,6 +332,7 @@ public override void OnApplyTemplate() this.ItemsPanelContainer = this.GetTemplateChild("PART_ItemsPanelContainer") as UIElement; this.SelectedContentHost = this.GetTemplateChild("PART_SelectedContentHost") as ContentPresenter; + this.BackButton = this.GetTemplateChild("PART_BackButton") as UIElement; } /// diff --git a/Fluent.Ribbon/Extensions/UIElementExtensions.cs b/Fluent.Ribbon/Extensions/UIElementExtensions.cs new file mode 100644 index 000000000..d5747622e --- /dev/null +++ b/Fluent.Ribbon/Extensions/UIElementExtensions.cs @@ -0,0 +1,13 @@ +namespace Fluent.Extensions; + +using System.Windows; +using System.Windows.Automation.Peers; + +internal static class UIElementExtensions +{ + public static AutomationPeer? GetOrCreateAutomationPeer(this UIElement element) + { + return UIElementAutomationPeer.FromElement(element) + ?? UIElementAutomationPeer.CreatePeerForElement(element); + } +} \ No newline at end of file diff --git a/Fluent.Ribbon/Themes/Controls/BackstageTabControl.xaml b/Fluent.Ribbon/Themes/Controls/BackstageTabControl.xaml index 4254cf4db..9461c7437 100644 --- a/Fluent.Ribbon/Themes/Controls/BackstageTabControl.xaml +++ b/Fluent.Ribbon/Themes/Controls/BackstageTabControl.xaml @@ -197,7 +197,7 @@ VerticalAlignment="Top" IsEnabled="{TemplateBinding IsWindowSteeringHelperEnabled}" /> -