diff --git a/src/Avalonia.Controls/Automation/Peers/RadioButtonAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/RadioButtonAutomationPeer.cs new file mode 100644 index 0000000000..ea4e37adba --- /dev/null +++ b/src/Avalonia.Controls/Automation/Peers/RadioButtonAutomationPeer.cs @@ -0,0 +1,70 @@ +using System; +using Avalonia.Automation; +using Avalonia.Automation.Peers; +using Avalonia.Automation.Provider; + +namespace Avalonia.Controls.Automation.Peers +{ + public class RadioButtonAutomationPeer : ToggleButtonAutomationPeer, ISelectionItemProvider + { + public RadioButtonAutomationPeer(RadioButton owner) : base(owner) + { + owner.PropertyChanged += (a, e) => + { + if (e.Property == RadioButton.IsCheckedProperty) + { + RaiseToggleStatePropertyChangedEvent((bool)e.OldValue, (bool)e.NewValue); + } + + }; + } + + override protected string GetClassNameCore() + { + return "RadioButton"; + } + + override protected AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.RadioButton; + } + + public bool IsSelected => ((RadioButton)Owner).IsChecked == true; + + public ISelectionProvider? SelectionContainer + { + get + { + return null; + } + } + + public void AddToSelection() + { + if (((RadioButton)Owner).IsChecked != true) + throw new InvalidOperationException("Operation cannot be performed"); + } + + public void RemoveFromSelection() + { + if (((RadioButton)Owner).IsChecked == true) + throw new InvalidOperationException("Operation cannot be performed"); + } + + public void Select() + { + if (!IsEnabled()) + throw new InvalidOperationException("Element is disabled thus it cannot be selected"); + + ((RadioButton)Owner).IsChecked = true; + } + + internal virtual void RaiseToggleStatePropertyChangedEvent(bool? oldValue, bool? newValue) + { + RaisePropertyChangedEvent( + SelectionItemPatternIdentifiers.IsSelectedProperty, + oldValue == true, + newValue == true); + } + } +} diff --git a/src/Avalonia.Controls/Automation/SelectionItemPatternIdentifiers.cs b/src/Avalonia.Controls/Automation/SelectionItemPatternIdentifiers.cs new file mode 100644 index 0000000000..418ae1f1fe --- /dev/null +++ b/src/Avalonia.Controls/Automation/SelectionItemPatternIdentifiers.cs @@ -0,0 +1,16 @@ +using Avalonia.Automation.Provider; + +namespace Avalonia.Automation +{ + /// + /// Contains values used as identifiers by . + /// + public static class SelectionItemPatternIdentifiers + { + /// Indicates the element is currently selected. + public static AutomationProperty IsSelectedProperty { get; } = new AutomationProperty(); + + /// Indicates the element is currently selected. + public static AutomationProperty SelectionContainerProperty { get; } = new AutomationProperty(); + } +} diff --git a/src/Avalonia.Controls/RadioButton.cs b/src/Avalonia.Controls/RadioButton.cs index b87be34a9d..87772aced7 100644 --- a/src/Avalonia.Controls/RadioButton.cs +++ b/src/Avalonia.Controls/RadioButton.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; +using Avalonia.Automation.Peers; +using Avalonia.Controls.Automation.Peers; using Avalonia.Controls.Primitives; using Avalonia.Reactive; using Avalonia.Rendering; @@ -147,6 +149,11 @@ namespace Avalonia.Controls } } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new RadioButtonAutomationPeer(this); + } + private void SetGroupName(string? newGroupName) { var oldGroupName = GroupName; diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs index 48ebd4068e..3eeedc4b5d 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs @@ -41,6 +41,8 @@ namespace Avalonia.Win32.Automation { SelectionPatternIdentifiers.CanSelectMultipleProperty, UiaPropertyId.SelectionCanSelectMultiple }, { SelectionPatternIdentifiers.IsSelectionRequiredProperty, UiaPropertyId.SelectionIsSelectionRequired }, { SelectionPatternIdentifiers.SelectionProperty, UiaPropertyId.SelectionSelection }, + { SelectionItemPatternIdentifiers.IsSelectedProperty, UiaPropertyId.SelectionItemIsSelected }, + { SelectionItemPatternIdentifiers.SelectionContainerProperty, UiaPropertyId.SelectionItemSelectionContainer } }; private static ConditionalWeakTable s_nodes = new();