diff --git a/src/EditorFeatures/Core/EditorFeatures.csproj b/src/EditorFeatures/Core/EditorFeatures.csproj
index b7bd8906c5d9ecb7b74597a5103dca8c330e1d7d..70df6d05fe564344c375ee898fb55ded4f01bd5d 100644
--- a/src/EditorFeatures/Core/EditorFeatures.csproj
+++ b/src/EditorFeatures/Core/EditorFeatures.csproj
@@ -108,6 +108,7 @@
+
diff --git a/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs b/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs
index b271086368f9ce88a724ced79fc915a26010177e..7f05a43d1c3c0a84cfd05a3ed6b96f988ccb0238 100644
--- a/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs
+++ b/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs
@@ -188,6 +188,15 @@ internal class EditorFeaturesResources {
}
}
+ ///
+ /// Looks up a localized string similar to An inline rename session is active.
+ ///
+ internal static string An_inline_rename_session_is_active {
+ get {
+ return ResourceManager.GetString("An_inline_rename_session_is_active", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to _Apply.
///
diff --git a/src/EditorFeatures/Core/EditorFeaturesResources.resx b/src/EditorFeatures/Core/EditorFeaturesResources.resx
index ca8aacef83d57454fc37027d3da1355ac5657ad9..219f96e03041d2432b249ac5ffbd9b0b33cc96d7 100644
--- a/src/EditorFeatures/Core/EditorFeaturesResources.resx
+++ b/src/EditorFeatures/Core/EditorFeaturesResources.resx
@@ -754,4 +754,8 @@ Do you want to proceed?
'{0}' declarations
+
+ An inline rename session is active
+ For screenreaders
+
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/Dashboard.xaml.cs b/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/Dashboard.xaml.cs
index 63e51412f1a44267400841f2d0c758b8f5a3303b..191e413cd03d70abb4a6fb2b344151538f59d54c 100644
--- a/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/Dashboard.xaml.cs
+++ b/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/Dashboard.xaml.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
+using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.VisualStudio.Text.Editor;
@@ -62,11 +63,27 @@ internal partial class Dashboard : UserControl, IDisposable
// Find UI doesn't exist in ETA.
}
+ // Once the Dashboard is loaded, the visual tree is completely created and the
+ // UIAutomation system has discovered and connected the AutomationPeer to the tree,
+ // allowing us to raise the AutomationFocusChanged event and have it process correctly.
+ // for us to set up the AutomationPeer
+ this.Loaded += Dashboard_Loaded;
+
this.Focus();
textView.Caret.IsHidden = false;
ShouldReceiveKeyboardNavigation = false;
}
+ private void Dashboard_Loaded(object sender, RoutedEventArgs e)
+ {
+ // Move automation focus to the Dashboard so that screenreaders will announce that the
+ // session has begun.
+ if (AutomationPeer.ListenerExists(AutomationEvents.AutomationFocusChanged))
+ {
+ UIElementAutomationPeer.CreatePeerForElement(this)?.RaiseAutomationEvent(AutomationEvents.AutomationFocusChanged);
+ }
+ }
+
private void ShowCaret()
{
// We actually want the caret visible even though the view isn't explicitly focused.
@@ -178,6 +195,11 @@ protected override void OnAccessKey(AccessKeyEventArgs e)
}
}
+ protected override AutomationPeer OnCreateAutomationPeer()
+ {
+ return new DashboardAutomationPeer(this);
+ }
+
private void DisconnectFromPresentationSource()
{
if (_rootInputElement != null)
@@ -272,6 +294,8 @@ public void Dispose()
((UIElement)_findAdornmentLayer).LayoutUpdated -= FindAdornmentCanvas_LayoutUpdated;
}
+ this.Loaded -= Dashboard_Loaded;
+
_model.Dispose();
PresentationSource.RemoveSourceChangedHandler(this, OnPresentationSourceChanged);
}
diff --git a/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/DashboardAutomationPeer.cs b/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/DashboardAutomationPeer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b53ba29dc904db68f1e80d32332f81e136c87e3e
--- /dev/null
+++ b/src/EditorFeatures/Core/Implementation/InlineRename/Dashboard/DashboardAutomationPeer.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Windows.Automation.Peers;
+using System.Windows.Controls;
+
+namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
+{
+ ///
+ /// Custom AutomationPeer to announce that an Inline Rename session has begun.
+ ///
+ internal class DashboardAutomationPeer : UserControlAutomationPeer
+ {
+ public DashboardAutomationPeer(UserControl owner) : base(owner)
+ {
+ }
+
+ protected override bool HasKeyboardFocusCore()
+ {
+ return true;
+ }
+
+ protected override bool IsKeyboardFocusableCore()
+ {
+ return true;
+ }
+
+ protected override string GetNameCore()
+ {
+ return EditorFeaturesResources.An_inline_rename_session_is_active;
+ }
+
+ protected override AutomationControlType GetAutomationControlTypeCore()
+ {
+ return AutomationControlType.Edit;
+ }
+ }
+}