diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj b/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj index f26ab3689d2..327818b45dc 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj @@ -392,6 +392,7 @@ + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationHeadingLevel.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationHeadingLevel.cs new file mode 100644 index 00000000000..c9632f6f3f5 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationHeadingLevel.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// +// +// +// Description: Enumeration for possible values of AutomationProperties.HeadingLevel +// + +namespace System.Windows.Automation +{ + /// + /// Describes the heading level of a control + /// + public enum AutomationHeadingLevel + { + /// + /// The element does not have a heading level + /// + None = 0, + + /// + /// The element has a heading level of 1 + /// + Level1, + + /// + /// The element has a heading level of 2 + /// + Level2, + + /// + /// The element has a heading level of 3 + /// + Level3, + + /// + /// The element has a heading level of 4 + /// + Level4, + + /// + /// The element has a heading level of 5 + /// + Level5, + + /// + /// The element has a heading level of 6 + /// + Level6, + + /// + /// The element has a heading level of 7 + /// + Level7, + + /// + /// The element has a heading level of 8 + /// + Level8, + + /// + /// The element has a heading level of 9 + /// + Level9, + } + +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationProperties.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationProperties.cs index cc47684ef1f..cda7d3f0e8a 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationProperties.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/AutomationProperties.cs @@ -594,6 +594,75 @@ public static int GetSizeOfSet(DependencyObject element) } #endregion + #region HeadingLevel + public static readonly DependencyProperty HeadingLevelProperty = + DependencyProperty.RegisterAttached( + "HeadingLevel", + typeof(AutomationHeadingLevel), + typeof(AutomationProperties), + new UIPropertyMetadata(AutomationHeadingLevel.None)); + + /// + /// Helper for setting HeadingLevel property on a DependencyObject. + /// + public static void SetHeadingLevel(DependencyObject element, AutomationHeadingLevel value) + { + if (element == null) + { + throw new ArgumentNullException(nameof(element)); + } + + element.SetValue(HeadingLevelProperty, value); + } + + /// + /// Helper for reading HeadingLevel property from a DependencyObject. + /// + public static AutomationHeadingLevel GetHeadingLevel(DependencyObject element) + { + if (element == null) + { + throw new ArgumentNullException(nameof(element)); + } + + return ((AutomationHeadingLevel)element.GetValue(HeadingLevelProperty)); + } + #endregion + + #region isDialog + public static readonly DependencyProperty IsDialogProperty = + DependencyProperty.RegisterAttached( + "IsDialog", + typeof(bool), + typeof(AutomationProperties), + new UIPropertyMetadata(false)); + + /// + /// Helper for setting IsDialog property on a DependencyObject. + /// + public static void SetIsDialog(DependencyObject element, bool value) + { + if(element == null) + { + throw new ArgumentNullException(nameof(element)); + } + element.SetValue(IsDialogProperty, value); + } + + /// + /// Helper for reading IsDialog property from a DependencyObject. + /// + public static bool GetIsDialog(DependencyObject element) + { + if (element == null) + { + throw new ArgumentNullException(nameof(element)); + } + + return (bool)element.GetValue(IsDialogProperty); + } + #endregion + #region private implementation // Validation callback for string properties private static bool IsNotNull(object value) @@ -608,4 +677,3 @@ private static bool IsNotNull(object value) #endregion } } - diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/AutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/AutomationPeer.cs index c0517836bde..7a53918c9e7 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/AutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/AutomationPeer.cs @@ -652,6 +652,11 @@ virtual protected string GetLocalizedControlTypeCore() /// abstract protected bool IsControlElementCore(); + /// + virtual protected bool IsDialogCore(){ + return false; + } + /// abstract protected AutomationPeer GetLabeledByCore(); @@ -703,6 +708,13 @@ virtual protected int GetPositionInSetCore() return AutomationProperties.AutomationPositionInSetDefault; } + /// + /// Override this method to provide UIAutomation with the heading level of this element. + /// + virtual protected AutomationHeadingLevel GetHeadingLevelCore() + { + return AutomationHeadingLevel.None; + } // // INTERNAL STUFF - NOT OVERRIDABLE @@ -1263,6 +1275,104 @@ public int GetSizeOfSet() return result; } + /// + /// Attempt to get the value for the HeadingLevel property. + /// + /// + /// This public call cannot be attempted if another public call is in progress. + /// + /// + /// The value for the HeadingLevel property. + /// + public AutomationHeadingLevel GetHeadingLevel() + { + AutomationHeadingLevel result = AutomationHeadingLevel.None; + + if (_publicCallInProgress) + throw new InvalidOperationException(SR.Get(SRID.Automation_RecursivePublicCall)); + + try + { + _publicCallInProgress = true; + result = GetHeadingLevelCore(); + } + finally + { + _publicCallInProgress = false; + } + return result; + } + + + private enum HeadingLevel + { + None = 80050, + Level1, + Level2, + Level3, + Level4, + Level5, + Level6, + Level7, + Level8, + Level9, + } + private static HeadingLevel ConvertHeadingLevelToId(AutomationHeadingLevel value){ + switch(value) + { + case AutomationHeadingLevel.None: + return HeadingLevel.None; + case AutomationHeadingLevel.Level1: + return HeadingLevel.Level1; + case AutomationHeadingLevel.Level2: + return HeadingLevel.Level2; + case AutomationHeadingLevel.Level3: + return HeadingLevel.Level3; + case AutomationHeadingLevel.Level4: + return HeadingLevel.Level4; + case AutomationHeadingLevel.Level5: + return HeadingLevel.Level5; + case AutomationHeadingLevel.Level6: + return HeadingLevel.Level6; + case AutomationHeadingLevel.Level7: + return HeadingLevel.Level7; + case AutomationHeadingLevel.Level8: + return HeadingLevel.Level8; + case AutomationHeadingLevel.Level9: + return HeadingLevel.Level9; + default: + return HeadingLevel.None; + } + } + + + /// + /// Attempt to get the value for the IsDialog property. + /// + /// + /// This public call cannot be attempted if another public call is in progress. + /// + /// + /// The value for the IsDialog property. + /// + public bool IsDialog() + { + bool result = false; + if(_publicCallInProgress) + throw new InvalidOperationException(SR.Get(SRID.Automation_RecursivePublicCall)); + + try + { + _publicCallInProgress = true; + result = IsDialogCore(); + } + finally + { + _publicCallInProgress = false; + } + return result; + } + /// /// Attempt to get the value for the PositionInSet property. /// @@ -1756,7 +1866,7 @@ private void RaisePropertyChangedInternal(IRawElementProviderSimple provider, #endif } - // InvalidateLimit – lower bound for raising ChildrenInvalidated StructureChange event + // InvalidateLimit is the lower bound for raising ChildrenInvalidated StructureChange event internal void UpdateChildrenInternal(int invalidateLimit) { List oldChildren = _children; @@ -1989,7 +2099,7 @@ internal void UpdateSubtree() /// /// propagate the new value for AncestorsInvalid through the parent chain, - /// use EventSource (wrapper) peers whenever available as it’s the one connected to the tree. + /// use EventSource (wrapper) peers whenever available as it's the one connected to the tree. /// internal void InvalidateAncestorsRecursive() { @@ -2061,6 +2171,10 @@ internal object GetPropertyValue(int propertyId) if (getProperty != null) { result = getProperty(this); + if(AutomationElementIdentifiers.HeadingLevelProperty != null && propertyId == AutomationElementIdentifiers.HeadingLevelProperty.Id) + { + result = ConvertHeadingLevelToId((AutomationHeadingLevel)result); + } } return result; @@ -2312,6 +2426,14 @@ private static void Initialize() { s_propertyInfo[AutomationElementIdentifiers.PositionInSetProperty.Id] = new GetProperty(GetPositionInSet); } + if (AutomationElementIdentifiers.HeadingLevelProperty != null) + { + s_propertyInfo[AutomationElementIdentifiers.HeadingLevelProperty.Id] = new GetProperty(GetHeadingLevel); + } + if (AutomationElementIdentifiers.IsDialogProperty != null) + { + s_propertyInfo[AutomationElementIdentifiers.IsDialogProperty.Id] = new GetProperty(IsDialog); + } } private delegate object WrapObject(AutomationPeer peer, object iface); @@ -2363,6 +2485,8 @@ internal PatternInfo(int id, WrapObject wrapObject, PatternInterface patternInte private static object GetControllerFor(AutomationPeer peer) { return peer.GetControllerForProviderArray(); } private static object GetSizeOfSet(AutomationPeer peer) { return peer.GetSizeOfSet(); } private static object GetPositionInSet(AutomationPeer peer) { return peer.GetPositionInSet(); } + private static object GetHeadingLevel(AutomationPeer peer) { return peer.GetHeadingLevel(); } + private static object IsDialog(AutomationPeer peer) { return peer.IsDialog(); } private static Hashtable s_patternInfo; private static Hashtable s_propertyInfo; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/ContentElementAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/ContentElementAutomationPeer.cs index 59d15b12afe..95441e38450 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/ContentElementAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/ContentElementAutomationPeer.cs @@ -213,6 +213,14 @@ override protected bool IsEnabledCore() return _owner.IsEnabled; } + /// + /// + /// + override protected bool IsDialogCore() + { + return AutomationProperties.GetIsDialog(_owner); + } + /// /// /// @@ -287,6 +295,15 @@ override protected int GetSizeOfSetCore() return AutomationProperties.GetSizeOfSet(_owner); } + /// + /// Provides a value for UIAutomation's HeadingLevel property + /// Reads and returns the value + /// + override protected AutomationHeadingLevel GetHeadingLevelCore() + { + return AutomationProperties.GetHeadingLevel(_owner); + } + /// /// /// diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElement3DAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElement3DAutomationPeer.cs index 7e07bdad991..e8727abeb04 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElement3DAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElement3DAutomationPeer.cs @@ -317,6 +317,12 @@ override protected bool IsEnabledCore() return _owner.IsEnabled; } + /// + override protected bool IsDialogCore() + { + return AutomationProperties.GetIsDialog(_owner); + } + /// override protected bool IsPasswordCore() { @@ -386,6 +392,15 @@ override protected int GetSizeOfSetCore() return AutomationProperties.GetSizeOfSet(_owner); } + /// + /// Provides a value for UIAutomation's HeadingLevel property + /// Reads and returns the value + /// + override protected AutomationHeadingLevel GetHeadingLevelCore() + { + return AutomationProperties.GetHeadingLevel(_owner); + } + // // M E T H O D S // diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElementAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElementAutomationPeer.cs index 211a7450438..baab86741a9 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElementAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/UIElementAutomationPeer.cs @@ -365,6 +365,12 @@ override protected bool IsEnabledCore() return _owner.IsEnabled; } + /// + override protected bool IsDialogCore() + { + return AutomationProperties.GetIsDialog(_owner); + } + /// override protected bool IsPasswordCore() { @@ -487,6 +493,15 @@ override protected int GetSizeOfSetCore() return sizeOfSet; } + /// + /// Provides a value for UIAutomation's HeadingLevel property + /// Reads and returns the value + /// + override protected AutomationHeadingLevel GetHeadingLevelCore() + { + return AutomationProperties.GetHeadingLevel(_owner); + } + // // M E T H O D S // diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/ref/PresentationCore.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/ref/PresentationCore.cs index 787b6ad7e18..6401369209b 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/ref/PresentationCore.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/ref/PresentationCore.cs @@ -2126,13 +2126,30 @@ public enum AutomationLiveSetting Polite = 1, Assertive = 2, } + + public enum AutomationHeadingLevel + { + None = 0, + Level1, + Level2, + Level3, + Level4, + Level5, + Level6, + Level7, + Level8, + Level9, + } + public static partial class AutomationProperties { public static readonly System.Windows.DependencyProperty AcceleratorKeyProperty; public static readonly System.Windows.DependencyProperty AccessKeyProperty; public static readonly System.Windows.DependencyProperty AutomationIdProperty; + public static readonly System.Windows.DependencyProperty HeadingLevelProperty; public static readonly System.Windows.DependencyProperty HelpTextProperty; public static readonly System.Windows.DependencyProperty IsColumnHeaderProperty; + public static readonly System.Windows.DependencyProperty IsDialogProperty; public static readonly System.Windows.DependencyProperty IsOffscreenBehaviorProperty; public static readonly System.Windows.DependencyProperty IsRequiredForFormProperty; public static readonly System.Windows.DependencyProperty IsRowHeaderProperty; @@ -2146,8 +2163,10 @@ public static partial class AutomationProperties public static string GetAcceleratorKey(System.Windows.DependencyObject element) { throw null; } public static string GetAccessKey(System.Windows.DependencyObject element) { throw null; } public static string GetAutomationId(System.Windows.DependencyObject element) { throw null; } + public static System.Windows.Automation.AutomationHeadingLevel GetHeadingLevel(System.Windows.DependencyObject element) { throw null; } public static string GetHelpText(System.Windows.DependencyObject element) { throw null; } public static bool GetIsColumnHeader(System.Windows.DependencyObject element) { throw null; } + public static bool GetIsDialog(System.Windows.DependencyObject element) { throw null; } public static System.Windows.Automation.IsOffscreenBehavior GetIsOffscreenBehavior(System.Windows.DependencyObject element) { throw null; } public static bool GetIsRequiredForForm(System.Windows.DependencyObject element) { throw null; } public static bool GetIsRowHeader(System.Windows.DependencyObject element) { throw null; } @@ -2161,8 +2180,10 @@ public static partial class AutomationProperties public static void SetAcceleratorKey(System.Windows.DependencyObject element, string value) { } public static void SetAccessKey(System.Windows.DependencyObject element, string value) { } public static void SetAutomationId(System.Windows.DependencyObject element, string value) { } + public static void SetHeadingLevel(System.Windows.DependencyObject element, System.Windows.Automation.AutomationHeadingLevel value) { } public static void SetHelpText(System.Windows.DependencyObject element, string value) { } public static void SetIsColumnHeader(System.Windows.DependencyObject element, bool value) { } + public static void SetIsDialog(System.Windows.DependencyObject element, bool value) { } public static void SetIsOffscreenBehavior(System.Windows.DependencyObject element, System.Windows.Automation.IsOffscreenBehavior value) { } public static void SetIsRequiredForForm(System.Windows.DependencyObject element, bool value) { } public static void SetIsRowHeader(System.Windows.DependencyObject element, bool value) { } @@ -2277,9 +2298,12 @@ protected AutomationPeer() { } protected abstract System.Windows.Point GetClickablePointCore(); public System.Collections.Generic.List GetControlledPeers() { throw null; } protected virtual System.Collections.Generic.List GetControlledPeersCore() { throw null; } + public System.Windows.Automation.AutomationHeadingLevel GetHeadingLevel() { throw null; } + protected virtual System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } public string GetHelpText() { throw null; } protected abstract string GetHelpTextCore(); protected virtual System.Windows.Automation.Peers.HostedWindowWrapper GetHostRawElementProviderCore() { throw null; } + public string GetItemStatus() { throw null; } protected abstract string GetItemStatusCore(); public string GetItemType() { throw null; } @@ -2309,6 +2333,8 @@ public void InvalidatePeer() { } protected abstract bool IsContentElementCore(); public bool IsControlElement() { throw null; } protected abstract bool IsControlElementCore(); + public bool IsDialog() { throw null; } + protected virtual bool IsDialogCore() { throw null; } public bool IsEnabled() { throw null; } protected abstract bool IsEnabledCore(); public bool IsKeyboardFocusable() { throw null; } @@ -2343,6 +2369,7 @@ public ContentElementAutomationPeer(System.Windows.ContentElement owner) { } protected override System.Collections.Generic.List GetChildrenCore() { throw null; } protected override string GetClassNameCore() { throw null; } protected override System.Windows.Point GetClickablePointCore() { throw null; } + protected override System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } protected override string GetHelpTextCore() { throw null; } protected override string GetItemStatusCore() { throw null; } protected override string GetItemTypeCore() { throw null; } @@ -2356,6 +2383,7 @@ public ContentElementAutomationPeer(System.Windows.ContentElement owner) { } protected override bool HasKeyboardFocusCore() { throw null; } protected override bool IsContentElementCore() { throw null; } protected override bool IsControlElementCore() { throw null; } + protected override bool IsDialogCore() { throw null; } protected override bool IsEnabledCore() { throw null; } protected override bool IsKeyboardFocusableCore() { throw null; } protected override bool IsOffscreenCore() { throw null; } @@ -2413,6 +2441,7 @@ public UIElement3DAutomationPeer(System.Windows.UIElement3D owner) { } protected override System.Collections.Generic.List GetChildrenCore() { throw null; } protected override string GetClassNameCore() { throw null; } protected override System.Windows.Point GetClickablePointCore() { throw null; } + protected override System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } protected override string GetHelpTextCore() { throw null; } protected override string GetItemStatusCore() { throw null; } protected override string GetItemTypeCore() { throw null; } @@ -2426,6 +2455,7 @@ public UIElement3DAutomationPeer(System.Windows.UIElement3D owner) { } protected override bool HasKeyboardFocusCore() { throw null; } protected override bool IsContentElementCore() { throw null; } protected override bool IsControlElementCore() { throw null; } + protected override bool IsDialogCore() { throw null; } protected override bool IsEnabledCore() { throw null; } protected override bool IsKeyboardFocusableCore() { throw null; } protected override bool IsOffscreenCore() { throw null; } @@ -2447,6 +2477,7 @@ public UIElementAutomationPeer(System.Windows.UIElement owner) { } protected override System.Collections.Generic.List GetChildrenCore() { throw null; } protected override string GetClassNameCore() { throw null; } protected override System.Windows.Point GetClickablePointCore() { throw null; } + protected override System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } protected override string GetHelpTextCore() { throw null; } protected override string GetItemStatusCore() { throw null; } protected override string GetItemTypeCore() { throw null; } @@ -2460,6 +2491,7 @@ public UIElementAutomationPeer(System.Windows.UIElement owner) { } protected override bool HasKeyboardFocusCore() { throw null; } protected override bool IsContentElementCore() { throw null; } protected override bool IsControlElementCore() { throw null; } + protected override bool IsDialogCore() { throw null; } protected override bool IsEnabledCore() { throw null; } protected override bool IsKeyboardFocusableCore() { throw null; } protected override bool IsOffscreenCore() { throw null; } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DataGridCellItemAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DataGridCellItemAutomationPeer.cs index 9466211a551..4a6cb628c7e 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DataGridCellItemAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DataGridCellItemAutomationPeer.cs @@ -363,6 +363,24 @@ protected override int GetSizeOfSetCore() return size; } + /// + override protected AutomationHeadingLevel GetHeadingLevelCore() + { + AutomationPeer wrapperPeer = OwningCellPeer; + AutomationHeadingLevel headingLevel = AutomationHeadingLevel.None; + + if(wrapperPeer != null) + { + headingLevel = wrapperPeer.GetHeadingLevel(); + } + else + { + ThrowElementNotAvailableException(); + } + + return headingLevel; + } + override internal Rect GetVisibleBoundingRectCore() { AutomationPeer wrapperPeer = OwningCellPeer; @@ -405,6 +423,18 @@ protected override bool IsControlElementCore() return true; } + /// + protected override bool IsDialogCore() + { + AutomationPeer wrapperPeer = OwningCellPeer; + if (wrapperPeer != null) + return wrapperPeer.IsDialog(); + else + ThrowElementNotAvailableException(); + + return false; + } + /// protected override bool IsEnabledCore() { diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DateTimeAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DateTimeAutomationPeer.cs index 6ed7fd6a0fc..6d6663d3865 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DateTimeAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DateTimeAutomationPeer.cs @@ -459,6 +459,24 @@ protected override int GetSizeOfSetCore() return AutomationProperties.AutomationSizeOfSetDefault; } + /// + override protected AutomationHeadingLevel GetHeadingLevelCore() + { + AutomationPeer wrapperPeer = WrapperPeer; + AutomationHeadingLevel headingLevel = AutomationHeadingLevel.None; + + if(wrapperPeer != null) + { + headingLevel = wrapperPeer.GetHeadingLevel(); + } + else + { + ThrowElementNotAvailableException(); + } + + return headingLevel; + } + internal override Rect GetVisibleBoundingRectCore() { AutomationPeer wrapperPeer = WrapperPeer; @@ -510,6 +528,21 @@ protected override bool IsControlElementCore() return true; } + protected override bool IsDialogCore() + { + AutomationPeer wrapperPeer = WrapperPeer; + if (wrapperPeer != null) + { + return wrapperPeer.IsDialog(); + } + else + { + ThrowElementNotAvailableException(); + } + + return false; + } + protected override bool IsEnabledCore() { AutomationPeer wrapperPeer = WrapperPeer; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemAutomationPeer.cs index d8f951ae212..184f9149ba2 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemAutomationPeer.cs @@ -232,6 +232,24 @@ protected override AutomationOrientation GetOrientationCore() return AutomationOrientation.None; } + /// + override protected AutomationHeadingLevel GetHeadingLevelCore() + { + AutomationPeer wrapperPeer = GetWrapperPeer(); + AutomationHeadingLevel headingLevel = AutomationHeadingLevel.None; + + if(wrapperPeer != null) + { + headingLevel = wrapperPeer.GetHeadingLevel(); + } + else + { + ThrowElementNotAvailableException(); + } + + return headingLevel; + } + /// /// Gets the position of an item within a set. /// @@ -436,6 +454,18 @@ protected override bool IsEnabledCore() return false; } + /// + protected override bool IsDialogCore() + { + AutomationPeer wrapperPeer = GetWrapperPeer(); + if (wrapperPeer != null) + return wrapperPeer.IsDialog(); + else + ThrowElementNotAvailableException(); + + return false; + } + /// protected override bool IsPasswordCore() { diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/WindowAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/WindowAutomationPeer.cs index 25c5d7dcd3c..601e0031956 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/WindowAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/WindowAutomationPeer.cs @@ -88,7 +88,19 @@ override protected Rect GetBoundingRectangleCore() return bounds; } + + protected override bool IsDialogCore() + { + Window window = (Window)Owner; + if (MS.Internal.Helper.IsDefaultValue(AutomationProperties.IsDialogProperty, window)) + { + return window.IsShowingAsDialog; + } + else + { + return AutomationProperties.GetIsDialog(window); + } + } } } - diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs index d15232b2f15..5b558dd1f69 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs @@ -1279,6 +1279,17 @@ public WindowCollection OwnedWindows } } + /// + /// Gets Showing as dialog + /// + internal bool IsShowingAsDialog + { + get + { + return _showingAsDialog; + } + } + /// /// Sets/gets DialogResult /// diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs index 534e2813c0d..9fe48d1c8d7 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs @@ -2403,6 +2403,7 @@ public DataGridCellItemAutomationPeer(object item, System.Windows.Controls.DataG protected override System.Collections.Generic.List GetChildrenCore() { throw null; } protected override string GetClassNameCore() { throw null; } protected override System.Windows.Point GetClickablePointCore() { throw null; } + protected override System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } protected override string GetHelpTextCore() { throw null; } protected override string GetItemStatusCore() { throw null; } protected override string GetItemTypeCore() { throw null; } @@ -2417,6 +2418,7 @@ public DataGridCellItemAutomationPeer(object item, System.Windows.Controls.DataG protected override bool HasKeyboardFocusCore() { throw null; } protected override bool IsContentElementCore() { throw null; } protected override bool IsControlElementCore() { throw null; } + protected override bool IsDialogCore() { throw null; } protected override bool IsEnabledCore() { throw null; } protected override bool IsKeyboardFocusableCore() { throw null; } protected override bool IsOffscreenCore() { throw null; } @@ -2540,6 +2542,7 @@ internal DateTimeAutomationPeer() { } protected override System.Collections.Generic.List GetChildrenCore() { throw null; } protected override string GetClassNameCore() { throw null; } protected override System.Windows.Point GetClickablePointCore() { throw null; } + protected override System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } protected override string GetHelpTextCore() { throw null; } protected override string GetItemStatusCore() { throw null; } protected override string GetItemTypeCore() { throw null; } @@ -2554,6 +2557,7 @@ internal DateTimeAutomationPeer() { } protected override bool HasKeyboardFocusCore() { throw null; } protected override bool IsContentElementCore() { throw null; } protected override bool IsControlElementCore() { throw null; } + protected override bool IsDialogCore() { throw null; } protected override bool IsEnabledCore() { throw null; } protected override bool IsKeyboardFocusableCore() { throw null; } protected override bool IsOffscreenCore() { throw null; } @@ -2795,6 +2799,7 @@ protected ItemAutomationPeer(object item, System.Windows.Automation.Peers.ItemsC protected override System.Windows.Rect GetBoundingRectangleCore() { throw null; } protected override System.Collections.Generic.List GetChildrenCore() { throw null; } protected override System.Windows.Point GetClickablePointCore() { throw null; } + protected override System.Windows.Automation.AutomationHeadingLevel GetHeadingLevelCore() { throw null; } protected override string GetHelpTextCore() { throw null; } protected override string GetItemStatusCore() { throw null; } protected override string GetItemTypeCore() { throw null; } @@ -2808,6 +2813,7 @@ protected ItemAutomationPeer(object item, System.Windows.Automation.Peers.ItemsC protected override bool HasKeyboardFocusCore() { throw null; } protected override bool IsContentElementCore() { throw null; } protected override bool IsControlElementCore() { throw null; } + protected override bool IsDialogCore() { throw null; } protected override bool IsEnabledCore() { throw null; } protected override bool IsKeyboardFocusableCore() { throw null; } protected override bool IsOffscreenCore() { throw null; } diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OSVersionHelper.cs b/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OSVersionHelper.cs index 4917407dfa8..4a5f5ab664b 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OSVersionHelper.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OSVersionHelper.cs @@ -50,6 +50,8 @@ internal static class OSVersionHelper internal static bool IsOsWindows10RS5OrGreater { get; set; } + internal static bool IsOsWindows10RS4OrGreater { get; set; } + internal static bool IsOsWindows10RS3OrGreater { get; set; } internal static bool IsOsWindows10RS2OrGreater { get; set; } @@ -94,6 +96,8 @@ static OSVersionHelper() { IsOsWindows10RS5OrGreater = IsWindows10RS5OrGreater(); + IsOsWindows10RS4OrGreater = IsWindows10RS4OrGreater(); + IsOsWindows10RS3OrGreater = IsWindows10RS3OrGreater(); IsOsWindows10RS2OrGreater = IsWindows10RS2OrGreater(); @@ -139,6 +143,10 @@ static OSVersionHelper() [return: MarshalAs(UnmanagedType.I1)] static extern bool IsWindows10RS5OrGreater(); + [DllImport(DllImport.PresentationNative, CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + static extern bool IsWindows10RS4OrGreater(); + [DllImport(DllImport.PresentationNative, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] static extern bool IsWindows10RS3OrGreater(); @@ -221,6 +229,8 @@ internal static bool IsOsVersionOrGreater(OperatingSystemVersion osVer) { case OperatingSystemVersion.Windows10RS5: return IsOsWindows10RS5OrGreater; + case OperatingSystemVersion.Windows10RS4: + return IsOsWindows10RS4OrGreater; case OperatingSystemVersion.Windows10RS3: return IsOsWindows10RS3OrGreater; case OperatingSystemVersion.Windows10RS2: @@ -260,6 +270,10 @@ internal static OperatingSystemVersion GetOsVersion() { return OperatingSystemVersion.Windows10RS5; } + else if (IsOsWindows10RS4OrGreater) + { + return OperatingSystemVersion.Windows10RS4; + } else if (IsOsWindows10RS3OrGreater) { return OperatingSystemVersion.Windows10RS3; @@ -322,4 +336,4 @@ internal static OperatingSystemVersion GetOsVersion() #endregion } -} +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OperatingSystemVersion.cs b/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OperatingSystemVersion.cs index 59337f9fecf..6fa9aa2c507 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OperatingSystemVersion.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/InterOp/OperatingSystemVersion.cs @@ -46,6 +46,7 @@ internal enum OperatingSystemVersion Windows10RS1, Windows10RS2, Windows10RS3, + Windows10RS4, Windows10RS5, } -} +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/Schema.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/Schema.cs index 4ef6f790a05..e8cacb27ce6 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/Schema.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/Schema.cs @@ -209,6 +209,20 @@ internal static object ConvertToElementArray(object value) return els; } + private enum HeadingLevel + { + None = 80050, + Level1, + Level2, + Level3, + Level4, + Level5, + Level6, + Level7, + Level8, + Level9, + } + // Delegate versions of the above... private static AutomationPropertyConverter convertToBool = new AutomationPropertyConverter(ConvertToBool); private static AutomationPropertyConverter convertToRowOrColumnMajor = new AutomationPropertyConverter(ConvertToRowOrColumnMajor); @@ -274,6 +288,8 @@ internal static object ConvertToElementArray(object value) new AutomationPropertyInfo( null, AutomationElement.ItemStatusProperty, typeof(string), "" ), new AutomationPropertyInfo( null, AutomationElement.SizeOfSetProperty, typeof(int), -1 ), new AutomationPropertyInfo( null, AutomationElement.PositionInSetProperty, typeof(int), -1 ), + new AutomationPropertyInfo( null, AutomationElement.HeadingLevelProperty, typeof(HeadingLevel), HeadingLevel.None ), + new AutomationPropertyInfo( convertToBool, AutomationElement.IsDialogProperty, typeof(bool), false ), // Pattern Available properties // PropertyID Type Default value diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs index 0852348ee76..29bfbc02cfb 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs @@ -198,6 +198,16 @@ internal static AutomationElement Wrap(SafeNodeHandle hnode) /// public static readonly AutomationProperty PositionInSetProperty = AutomationElementIdentifiers.PositionInSetProperty; + /// + /// Property ID: HeadingLevel - Describes the heading level of an element. + /// + public static readonly AutomationProperty HeadingLevelProperty = AutomationElementIdentifiers.HeadingLevelProperty; + + /// + /// Property ID: IsDialog - Identifies if the automation element is a dialog. + /// + public static readonly AutomationProperty IsDialogProperty = AutomationElementIdentifiers.IsDialogProperty; + #region IsNnnnPatternAvailable properties /// Property that indicates whether the DockPattern is available for this AutomationElement public static readonly AutomationProperty IsDockPatternAvailableProperty = AutomationElementIdentifiers.IsDockPatternAvailableProperty; diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/ref/UIAutomationClient.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/ref/UIAutomationClient.cs index 75ac07964da..862c22d41c7 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/ref/UIAutomationClient.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/ref/UIAutomationClient.cs @@ -40,9 +40,11 @@ internal AutomationElement() { } public static readonly System.Windows.Automation.AutomationProperty CultureProperty; public static readonly System.Windows.Automation.AutomationProperty FrameworkIdProperty; public static readonly System.Windows.Automation.AutomationProperty HasKeyboardFocusProperty; + public static readonly System.Windows.Automation.AutomationProperty HeadingLevelProperty; public static readonly System.Windows.Automation.AutomationProperty HelpTextProperty; public static readonly System.Windows.Automation.AutomationProperty IsContentElementProperty; public static readonly System.Windows.Automation.AutomationProperty IsControlElementProperty; + public static readonly System.Windows.Automation.AutomationProperty IsDialogProperty; public static readonly System.Windows.Automation.AutomationProperty IsDockPatternAvailableProperty; public static readonly System.Windows.Automation.AutomationProperty IsEnabledProperty; public static readonly System.Windows.Automation.AutomationProperty IsExpandCollapsePatternAvailableProperty; diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/MS/Internal/Automation/AutomationIdentifierConstants.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/MS/Internal/Automation/AutomationIdentifierConstants.cs index fed8d758a06..47f7bd402dd 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/MS/Internal/Automation/AutomationIdentifierConstants.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/MS/Internal/Automation/AutomationIdentifierConstants.cs @@ -31,7 +31,23 @@ internal static class AutomationIdentifierConstants static AutomationIdentifierConstants() { - if (OSVersionHelper.IsOsWindows10RS2OrGreater) + if (OSVersionHelper.IsOsWindows10RS5OrGreater) + { + LastSupportedProperty = Properties.IsDialog; + LastSupportedEvent = Events.Changes; + LastSupportedPattern = Patterns.CustomNavigation; + LastSupportedTextAttribute = TextAttributes.SayAsInterpretAs; + LastSupportedControlType = ControlTypes.AppBar; + } + else if (OSVersionHelper.IsOsWindows10RS4OrGreater) + { + LastSupportedProperty = Properties.HeadingLevel; + LastSupportedEvent = Events.Changes; + LastSupportedPattern = Patterns.CustomNavigation; + LastSupportedTextAttribute = TextAttributes.SayAsInterpretAs; + LastSupportedControlType = ControlTypes.AppBar; + } + else if (OSVersionHelper.IsOsWindows10RS2OrGreater) { LastSupportedProperty = Properties.Size; LastSupportedEvent = Events.Changes; @@ -270,7 +286,14 @@ internal enum Properties OutlineThickness, CenterPoint, Rotatation, - Size + Size, + IsSelectionPattern2Available, + Selection2FirstSelectedItem, + Selection2LastSelectedItem, + Selection2CurrentSelectedItem, + Selection2ItemCount, + HeadingLevel, + IsDialog }; internal enum Events diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/System/Windows/Automation/AutomationElementIdentifiers.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/System/Windows/Automation/AutomationElementIdentifiers.cs index 2a421f9aaf7..e31b5ff9839 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/System/Windows/Automation/AutomationElementIdentifiers.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/System/Windows/Automation/AutomationElementIdentifiers.cs @@ -116,6 +116,12 @@ public static class AutomationElementIdentifiers /// Property ID: FrameworkId - Identifies the underlying UI framework's name for the element being accessed public static readonly AutomationProperty FrameworkIdProperty = AutomationProperty.Register(AutomationIdentifierConstants.Properties.FrameworkId, "AutomationElementIdentifiers.FrameworkIdProperty"); + /// Property ID: HeadingLevel - Describes the heading level of an element. + public static readonly AutomationProperty HeadingLevelProperty = AutomationProperty.Register(AutomationIdentifierConstants.Properties.HeadingLevel, "AutomationElementIdentifiers.HeadingLevelProperty"); + + /// Property ID: IsDialog - Identifies if the automation element is a dialog. + public static readonly AutomationProperty IsDialogProperty = AutomationProperty.Register(AutomationIdentifierConstants.Properties.IsDialog, "AutomationElementIdentifiers.IsDialogProperty"); + /// Property ID: IsRequiredForForm - Identifies weather an edit field is required to be filled out on a form public static readonly AutomationProperty IsRequiredForFormProperty = AutomationProperty.Register(AutomationIdentifierConstants.Properties.IsRequiredForForm, "AutomationElementIdentifiers.IsRequiredForFormProperty"); diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/ref/UIAutomationTypes.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/ref/UIAutomationTypes.cs index 622e1fbc6d6..455835c5b9d 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/ref/UIAutomationTypes.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationTypes/ref/UIAutomationTypes.cs @@ -28,9 +28,11 @@ public static partial class AutomationElementIdentifiers public static readonly System.Windows.Automation.AutomationProperty CultureProperty; public static readonly System.Windows.Automation.AutomationProperty FrameworkIdProperty; public static readonly System.Windows.Automation.AutomationProperty HasKeyboardFocusProperty; + public static readonly System.Windows.Automation.AutomationProperty HeadingLevelProperty; public static readonly System.Windows.Automation.AutomationProperty HelpTextProperty; public static readonly System.Windows.Automation.AutomationProperty IsContentElementProperty; public static readonly System.Windows.Automation.AutomationProperty IsControlElementProperty; + public static readonly System.Windows.Automation.AutomationProperty IsDialogProperty; public static readonly System.Windows.Automation.AutomationProperty IsDockPatternAvailableProperty; public static readonly System.Windows.Automation.AutomationProperty IsEnabledProperty; public static readonly System.Windows.Automation.AutomationProperty IsExpandCollapsePatternAvailableProperty;