Browse Source

Added automation peer for Expander control (#20475)

* Added `ExpanderAutomationPeer` for `Expander` control

* Use Group/"group" on UIA and NSAccessibilityDisclosureTriangleRole on AX

---------

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
pull/20505/head
Melissa 3 weeks ago
committed by GitHub
parent
commit
a2a1663f4b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      native/Avalonia.Native/src/OSX/automation.mm
  2. 2
      src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs
  3. 47
      src/Avalonia.Controls/Automation/Peers/ExpanderAutomationPeer.cs
  4. 7
      src/Avalonia.Controls/Expander.cs
  5. 1
      src/Avalonia.Native/avn.idl
  6. 1
      src/Windows/Avalonia.Win32.Automation/AutomationNode.cs

1
native/Avalonia.Native/src/OSX/automation.mm

@ -126,6 +126,7 @@
case AutomationHeaderItem: return NSAccessibilityButtonRole;
case AutomationTable: return NSAccessibilityTableRole;
case AutomationTitleBar: return NSAccessibilityGroupRole;
case AutomationExpander: return NSAccessibilityDisclosureTriangleRole;
// Treat unknown roles as generic group container items. Returning
// NSAccessibilityUnknownRole is also possible but makes the screen
// reader focus on the item instead of passing focus to child items.

2
src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs

@ -47,6 +47,7 @@ namespace Avalonia.Automation.Peers
Table,
TitleBar,
Separator,
Expander,
}
public enum AutomationLandmarkType
@ -536,6 +537,7 @@ namespace Avalonia.Automation.Peers
AutomationControlType.SplitButton => "split button",
AutomationControlType.HeaderItem => "header item",
AutomationControlType.TitleBar => "title bar",
AutomationControlType.Expander => "group",
AutomationControlType.None => (GetLandmarkType()?.ToString() ?? controlType.ToString()).ToLowerInvariant(),
_ => controlType.ToString().ToLowerInvariant(),
};

47
src/Avalonia.Controls/Automation/Peers/ExpanderAutomationPeer.cs

@ -0,0 +1,47 @@
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider;
namespace Avalonia.Controls.Automation.Peers
{
public class ExpanderAutomationPeer : ControlAutomationPeer,
IExpandCollapseProvider
{
public ExpanderAutomationPeer(Control owner)
: base(owner)
{
owner.PropertyChanged += OwnerPropertyChanged;
}
public new Expander Owner => (Expander)base.Owner;
public ExpandCollapseState ExpandCollapseState => ToState(Owner.IsExpanded);
public bool ShowsMenu => false;
public void Collapse() => Owner.IsExpanded = false;
public void Expand() => Owner.IsExpanded = true;
protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Expander;
}
private void OwnerPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == Expander.IsExpandedProperty)
{
RaisePropertyChangedEvent(
ExpandCollapsePatternIdentifiers.ExpandCollapseStateProperty,
ToState((bool)e.OldValue!),
ToState((bool)e.NewValue!));
}
}
private static ExpandCollapseState ToState(bool value)
{
return value ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed;
}
protected override bool IsContentElementCore() => true;
protected override bool IsControlElementCore() => true;
}
}

7
src/Avalonia.Controls/Expander.cs

@ -1,6 +1,8 @@
using System;
using System.Threading;
using Avalonia.Animation;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
@ -274,6 +276,11 @@ namespace Avalonia.Controls
}
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new ExpanderAutomationPeer(this);
}
/// <summary>
/// Updates the visual state of the control by applying latest PseudoClasses.
/// </summary>

1
src/Avalonia.Native/avn.idl

@ -652,6 +652,7 @@ enum AvnAutomationControlType
AutomationTable,
AutomationTitleBar,
AutomationSeparator,
AutomationExpander,
}
enum AvnLandmarkType

1
src/Windows/Avalonia.Win32.Automation/AutomationNode.cs

@ -357,6 +357,7 @@ namespace Avalonia.Win32.Automation
AutomationControlType.Table => UiaControlTypeId.Table,
AutomationControlType.TitleBar => UiaControlTypeId.TitleBar,
AutomationControlType.Separator => UiaControlTypeId.Separator,
AutomationControlType.Expander => UiaControlTypeId.Group,
_ => UiaControlTypeId.Custom,
};
}

Loading…
Cancel
Save