diff --git a/samples/ControlCatalog.Android/Resources/Resource.Designer.cs b/samples/ControlCatalog.Android/Resources/Resource.Designer.cs
index b1ca548e2c..6ac6673986 100644
--- a/samples/ControlCatalog.Android/Resources/Resource.Designer.cs
+++ b/samples/ControlCatalog.Android/Resources/Resource.Designer.cs
@@ -14,7 +14,7 @@ namespace ControlCatalog.Android
{
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.0.99.19")]
public partial class Resource
{
diff --git a/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs b/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs
index 83db67fcee..4046e60161 100644
--- a/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs
+++ b/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs
@@ -14,7 +14,7 @@ namespace Avalonia.AndroidTestApplication
{
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.0.99.19")]
public partial class Resource
{
diff --git a/src/Avalonia.Controls/Automation/AutomationPropertyChangedEventArgs.cs b/src/Avalonia.Controls/Automation/AutomationPropertyChangedEventArgs.cs
new file mode 100644
index 0000000000..b8018613f8
--- /dev/null
+++ b/src/Avalonia.Controls/Automation/AutomationPropertyChangedEventArgs.cs
@@ -0,0 +1,23 @@
+using System;
+
+#nullable enable
+
+namespace Avalonia.Automation
+{
+ public class AutomationPropertyChangedEventArgs : EventArgs
+ {
+ public AutomationPropertyChangedEventArgs(
+ AutomationProperty property,
+ object? oldValue,
+ object? newValue)
+ {
+ Property = property;
+ OldValue = oldValue;
+ NewValue = newValue;
+ }
+
+ public AutomationProperty Property { get; }
+ public object? OldValue { get; }
+ public object? NewValue { get; }
+ }
+}
diff --git a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs
index 85a0e665b2..757fe9e158 100644
--- a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
-using Avalonia.Automation.Platform;
#nullable enable
@@ -56,33 +54,6 @@ namespace Avalonia.Automation.Peers
///
public abstract class AutomationPeer
{
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The factory to use to create the platform automation node.
- ///
- protected AutomationPeer(IAutomationNodeFactory factory)
- {
- Node = factory.CreateNode(this);
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The platform automation node.
- ///
- protected AutomationPeer(IAutomationNode node)
- {
- Node = node;
- }
-
- ///
- /// Gets the related node in the platform UI Automation tree.
- ///
- public IAutomationNode Node { get; }
-
///
/// Attempts to bring the element associated with the automation peer into view.
///
@@ -188,18 +159,20 @@ namespace Avalonia.Automation.Peers
/// true if a context menu is present for the element; otherwise false.
public bool ShowContextMenu() => ShowContextMenuCore();
+ public event EventHandler? PropertyChanged;
+
///
/// Raises an event to notify the automation client of a changed property value.
///
- /// The property that changed.
+ /// The property that changed.
/// The previous value of the property.
/// The new value of the property.
public void RaisePropertyChangedEvent(
- AutomationProperty automationProperty,
+ AutomationProperty property,
object? oldValue,
object? newValue)
{
- Node.PropertyChanged(automationProperty, oldValue, newValue);
+ PropertyChanged?.Invoke(this, new AutomationPropertyChangedEventArgs(property, oldValue, newValue));
}
protected virtual string GetLocalizedControlTypeCore()
diff --git a/src/Avalonia.Controls/Automation/Peers/ButtonAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ButtonAutomationPeer.cs
index 66e5bd7b49..f5d6dce039 100644
--- a/src/Avalonia.Controls/Automation/Peers/ButtonAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ButtonAutomationPeer.cs
@@ -1,4 +1,3 @@
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
@@ -9,8 +8,8 @@ namespace Avalonia.Automation.Peers
public class ButtonAutomationPeer : ContentControlAutomationPeer,
IInvokeProvider
{
- public ButtonAutomationPeer(IAutomationNodeFactory factory, Button owner)
- : base(factory, owner)
+ public ButtonAutomationPeer(Button owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/CheckBoxAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/CheckBoxAutomationPeer.cs
index 4e98cc7746..7f4e492935 100644
--- a/src/Avalonia.Controls/Automation/Peers/CheckBoxAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/CheckBoxAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class CheckBoxAutomationPeer : ToggleButtonAutomationPeer
{
- public CheckBoxAutomationPeer(IAutomationNodeFactory factory, CheckBox owner)
- : base(factory, owner)
+ public CheckBoxAutomationPeer(CheckBox owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs
index d8225dbc40..c582c3d372 100644
--- a/src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
@@ -12,8 +11,8 @@ namespace Avalonia.Automation.Peers
{
private UnrealizedSelectionPeer[]? _selection;
- public ComboBoxAutomationPeer(IAutomationNodeFactory factory, ComboBox owner)
- : base(factory, owner)
+ public ComboBoxAutomationPeer(ComboBox owner)
+ : base(owner)
{
}
@@ -39,7 +38,7 @@ namespace Avalonia.Automation.Peers
// peer to represent the unrealized item.
if (Owner.SelectedItem is object selection)
{
- _selection ??= new[] { new UnrealizedSelectionPeer(Node.Factory, this) };
+ _selection ??= new[] { new UnrealizedSelectionPeer(this) };
_selection[0].Item = selection;
return _selection;
}
@@ -70,8 +69,7 @@ namespace Avalonia.Automation.Peers
private readonly ComboBoxAutomationPeer _owner;
private object? _item;
- public UnrealizedSelectionPeer(IAutomationNodeFactory factory, ComboBoxAutomationPeer owner)
- : base(factory)
+ public UnrealizedSelectionPeer(ComboBoxAutomationPeer owner)
{
_owner = owner;
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ComboBoxItemAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ComboBoxItemAutomationPeer.cs
index 06141ae835..70d29dbc87 100644
--- a/src/Avalonia.Controls/Automation/Peers/ComboBoxItemAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ComboBoxItemAutomationPeer.cs
@@ -1,5 +1,4 @@
using System;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
@@ -11,8 +10,8 @@ namespace Avalonia.Automation.Peers
{
public class ComboBoxItemAutomationPeer : ListItemAutomationPeer
{
- public ComboBoxItemAutomationPeer(IAutomationNodeFactory factory, ComboBoxItem owner)
- : base(factory, owner)
+ public ComboBoxItemAutomationPeer(ComboBoxItem owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ContentControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ContentControlAutomationPeer.cs
index db1c7e1aa7..08e4f2a926 100644
--- a/src/Avalonia.Controls/Automation/Peers/ContentControlAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ContentControlAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class ContentControlAutomationPeer : ControlAutomationPeer
{
- protected ContentControlAutomationPeer(IAutomationNodeFactory factory, ContentControl owner)
- : base(factory, owner)
+ protected ContentControlAutomationPeer(ContentControl owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ContextMenuAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ContextMenuAutomationPeer.cs
index 5631fcf581..3230f33506 100644
--- a/src/Avalonia.Controls/Automation/Peers/ContextMenuAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ContextMenuAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class ContextMenuAutomationPeer : ControlAutomationPeer
{
- public ContextMenuAutomationPeer(IAutomationNodeFactory factory, ContextMenu owner)
- : base(factory, owner)
+ public ContextMenuAutomationPeer(ContextMenu owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs
index bd4e9dfcf4..947c88a190 100644
--- a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.VisualTree;
@@ -19,15 +18,7 @@ namespace Avalonia.Automation.Peers
private AutomationPeer? _parent;
private bool _parentValid;
- public ControlAutomationPeer(IAutomationNodeFactory factory, Control owner)
- : base(factory)
- {
- Owner = owner ?? throw new ArgumentNullException("owner");
- Initialize();
- }
-
- protected ControlAutomationPeer(IAutomationNode node, Control owner)
- : base(node)
+ public ControlAutomationPeer(Control owner)
{
Owner = owner ?? throw new ArgumentNullException("owner");
Initialize();
@@ -35,15 +26,18 @@ namespace Avalonia.Automation.Peers
public Control Owner { get; }
- public static AutomationPeer GetOrCreatePeer(IAutomationNodeFactory factory, Control element)
+ public event EventHandler? ChildrenChanged;
+
+ public AutomationPeer GetOrCreate(Control element)
{
- element = element ?? throw new ArgumentNullException("element");
- return element.GetOrCreateAutomationPeer(factory);
+ if (element == Owner)
+ return this;
+ return CreatePeerForElement(element);
}
- public AutomationPeer GetOrCreatePeer(Control element)
+ public static AutomationPeer CreatePeerForElement(Control element)
{
- return element == Owner ? this : GetOrCreatePeer(Node.Factory, element);
+ return element.GetOrCreateAutomationPeer();
}
protected override void BringIntoViewCore() => Owner.BringIntoView();
@@ -79,7 +73,7 @@ namespace Avalonia.Automation.Peers
{
if (child is Control c && c.IsVisible)
{
- result.Add(GetOrCreatePeer(c));
+ result.Add(GetOrCreate(c));
}
}
@@ -89,7 +83,7 @@ namespace Avalonia.Automation.Peers
protected override AutomationPeer? GetLabeledByCore()
{
var label = AutomationProperties.GetLabeledBy(Owner);
- return label is Control c ? GetOrCreatePeer(c) : null;
+ return label is Control c ? GetOrCreate(c) : null;
}
protected override string? GetNameCore()
@@ -116,7 +110,7 @@ namespace Avalonia.Automation.Peers
protected void InvalidateChildren()
{
_childrenValid = false;
- Node!.ChildrenChanged();
+ ChildrenChanged?.Invoke(this, EventArgs.Empty);
}
///
@@ -185,7 +179,7 @@ namespace Avalonia.Automation.Peers
{
var parent = Owner.GetVisualParent();
if (parent is Control c)
- (GetOrCreatePeer(c) as ControlAutomationPeer)?.InvalidateChildren();
+ (GetOrCreate(c) as ControlAutomationPeer)?.InvalidateChildren();
}
else if (e.Property == Visual.TransformedBoundsProperty)
{
@@ -211,7 +205,7 @@ namespace Avalonia.Automation.Peers
{
if (parent is Control c)
{
- var parentPeer = GetOrCreatePeer(c);
+ var parentPeer = GetOrCreate(c);
parentPeer.GetChildren();
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ImageAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ImageAutomationPeer.cs
index ad88941299..4548341487 100644
--- a/src/Avalonia.Controls/Automation/Peers/ImageAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ImageAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class ImageAutomationPeer : ControlAutomationPeer
{
- public ImageAutomationPeer(IAutomationNodeFactory factory, Control owner)
- : base(factory, owner)
+ public ImageAutomationPeer(Control owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ItemsControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ItemsControlAutomationPeer.cs
index 6eed22e6cf..0d35920e19 100644
--- a/src/Avalonia.Controls/Automation/Peers/ItemsControlAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ItemsControlAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Automation.Provider;
+using Avalonia.Automation.Provider;
using Avalonia.Controls;
#nullable enable
@@ -11,8 +10,8 @@ namespace Avalonia.Automation.Peers
private bool _searchedForScrollable;
private IScrollProvider? _scroller;
- public ItemsControlAutomationPeer(IAutomationNodeFactory factory, ItemsControl owner)
- : base(factory, owner)
+ public ItemsControlAutomationPeer(ItemsControl owner)
+ : base(owner)
{
}
@@ -31,7 +30,7 @@ namespace Avalonia.Automation.Peers
if (!_searchedForScrollable)
{
if (Owner.GetValue(ListBox.ScrollProperty) is Control scrollable)
- _scroller = GetOrCreatePeer(scrollable) as IScrollProvider;
+ _scroller = GetOrCreate(scrollable) as IScrollProvider;
_searchedForScrollable = true;
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ListItemAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ListItemAutomationPeer.cs
index 1b9a8354a1..0621e81c1a 100644
--- a/src/Avalonia.Controls/Automation/Peers/ListItemAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ListItemAutomationPeer.cs
@@ -1,5 +1,4 @@
using System;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
@@ -12,8 +11,8 @@ namespace Avalonia.Automation.Peers
public class ListItemAutomationPeer : ContentControlAutomationPeer,
ISelectionItemProvider
{
- public ListItemAutomationPeer(IAutomationNodeFactory factory, ContentControl owner)
- : base(factory, owner)
+ public ListItemAutomationPeer(ContentControl owner)
+ : base(owner)
{
}
@@ -25,7 +24,7 @@ namespace Avalonia.Automation.Peers
{
if (Owner.Parent is Control parent)
{
- var parentPeer = GetOrCreatePeer(parent);
+ var parentPeer = GetOrCreate(parent);
return parentPeer as ISelectionProvider;
}
diff --git a/src/Avalonia.Controls/Automation/Peers/MenuAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/MenuAutomationPeer.cs
index 38cd7a8d41..e223a0864f 100644
--- a/src/Avalonia.Controls/Automation/Peers/MenuAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/MenuAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class MenuAutomationPeer : ControlAutomationPeer
{
- public MenuAutomationPeer(IAutomationNodeFactory factory, Menu owner)
- : base(factory, owner)
+ public MenuAutomationPeer(Menu owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/MenuItemAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/MenuItemAutomationPeer.cs
index 5ed1c5e579..1994f004d6 100644
--- a/src/Avalonia.Controls/Automation/Peers/MenuItemAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/MenuItemAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
using Avalonia.Controls.Primitives;
#nullable enable
@@ -8,8 +7,8 @@ namespace Avalonia.Automation.Peers
{
public class MenuItemAutomationPeer : ControlAutomationPeer
{
- public MenuItemAutomationPeer(IAutomationNodeFactory factory, MenuItem owner)
- : base(factory, owner)
+ public MenuItemAutomationPeer(MenuItem owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/NoneAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/NoneAutomationPeer.cs
index fa5e6c175e..2963144ebf 100644
--- a/src/Avalonia.Controls/Automation/Peers/NoneAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/NoneAutomationPeer.cs
@@ -1,4 +1,3 @@
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
#nullable enable
@@ -11,8 +10,8 @@ namespace Avalonia.Automation.Peers
///
public class NoneAutomationPeer : ControlAutomationPeer
{
- public NoneAutomationPeer(IAutomationNodeFactory factory, Control owner)
- : base(factory, owner)
+ public NoneAutomationPeer(Control owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/PopupAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/PopupAutomationPeer.cs
index 4bad8fd108..e6f827b942 100644
--- a/src/Avalonia.Controls/Automation/Peers/PopupAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/PopupAutomationPeer.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.VisualTree;
@@ -11,8 +10,8 @@ namespace Avalonia.Automation.Peers
{
public class PopupAutomationPeer : ControlAutomationPeer
{
- public PopupAutomationPeer(IAutomationNodeFactory factory, Popup owner)
- : base(factory, owner)
+ public PopupAutomationPeer(Popup owner)
+ : base(owner)
{
owner.Opened += PopupOpenedClosed;
owner.Closed += PopupOpenedClosed;
@@ -22,7 +21,7 @@ namespace Avalonia.Automation.Peers
{
var host = (IVisualTreeHost)Owner;
System.Diagnostics.Debug.WriteLine($"Popup children='{host}'");
- return host.Root is Control c ? new[] { GetOrCreatePeer(c) } : null;
+ return host.Root is Control c ? new[] { GetOrCreate(c) } : null;
}
protected override bool IsContentElementCore() => false;
@@ -46,7 +45,7 @@ namespace Avalonia.Automation.Peers
private AutomationPeer? GetPopupRoot()
{
var popupRoot = ((IVisualTreeHost)Owner).Root as Control;
- return popupRoot is object ? GetOrCreatePeer(popupRoot) : null;
+ return popupRoot is object ? GetOrCreate(popupRoot) : null;
}
}
}
diff --git a/src/Avalonia.Controls/Automation/Peers/PopupRootAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/PopupRootAutomationPeer.cs
index f7e06e83eb..fb717ef98b 100644
--- a/src/Avalonia.Controls/Automation/Peers/PopupRootAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/PopupRootAutomationPeer.cs
@@ -1,5 +1,4 @@
using System;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Primitives;
#nullable enable
@@ -8,8 +7,8 @@ namespace Avalonia.Automation.Peers
{
public class PopupRootAutomationPeer : WindowBaseAutomationPeer
{
- public PopupRootAutomationPeer(IAutomationNode node, PopupRoot owner)
- : base(node, owner)
+ public PopupRootAutomationPeer(PopupRoot owner)
+ : base(owner)
{
if (owner.IsVisible)
StartTrackingFocus();
diff --git a/src/Avalonia.Controls/Automation/Peers/RangeBaseAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/RangeBaseAutomationPeer.cs
index 31a2b7e7af..1bb487b161 100644
--- a/src/Avalonia.Controls/Automation/Peers/RangeBaseAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/RangeBaseAutomationPeer.cs
@@ -1,4 +1,3 @@
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls.Primitives;
@@ -8,8 +7,8 @@ namespace Avalonia.Automation.Peers
{
public abstract class RangeBaseAutomationPeer : ControlAutomationPeer, IRangeValueProvider
{
- public RangeBaseAutomationPeer(IAutomationNodeFactory factory, RangeBase owner)
- : base(factory, owner)
+ public RangeBaseAutomationPeer(RangeBase owner)
+ : base(owner)
{
owner.PropertyChanged += OwnerPropertyChanged;
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs
index 165df6c032..c2474bb9b8 100644
--- a/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ScrollViewerAutomationPeer.cs
@@ -1,5 +1,4 @@
using System;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Avalonia.Utilities;
@@ -10,8 +9,8 @@ namespace Avalonia.Automation.Peers
{
public class ScrollViewerAutomationPeer : ControlAutomationPeer, IScrollProvider
{
- public ScrollViewerAutomationPeer(IAutomationNodeFactory factory, ScrollViewer owner)
- : base(factory, owner)
+ public ScrollViewerAutomationPeer(ScrollViewer owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs
index b55f653a5d..f372e3b781 100644
--- a/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/SelectingItemsControlAutomationPeer.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
@@ -16,16 +15,16 @@ namespace Avalonia.Automation.Peers
{
private ISelectionModel _selection;
- protected SelectingItemsControlAutomationPeer(IAutomationNodeFactory factory, SelectingItemsControl owner)
- : base(factory, owner)
+ protected SelectingItemsControlAutomationPeer(SelectingItemsControl owner)
+ : base(owner)
{
_selection = owner.GetValue(ListBox.SelectionProperty);
_selection.SelectionChanged += OwnerSelectionChanged;
owner.PropertyChanged += OwnerPropertyChanged;
}
- public bool CanSelectMultiple => GetSelectionModeCore().HasFlagCustom(SelectionMode.Multiple);
- public bool IsSelectionRequired => GetSelectionModeCore().HasFlagCustom(SelectionMode.AlwaysSelected);
+ public bool CanSelectMultiple => GetSelectionModeCore().HasAllFlags(SelectionMode.Multiple);
+ public bool IsSelectionRequired => GetSelectionModeCore().HasAllFlags(SelectionMode.AlwaysSelected);
public IReadOnlyList GetSelection() => GetSelectionCore() ?? Array.Empty();
protected virtual IReadOnlyList? GetSelectionCore()
@@ -42,7 +41,7 @@ namespace Avalonia.Automation.Peers
if (container is Control c && ((IVisual)c).IsAttachedToVisualTree)
{
- var peer = GetOrCreatePeer(c);
+ var peer = GetOrCreate(c);
if (peer is object)
{
diff --git a/src/Avalonia.Controls/Automation/Peers/SliderAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/SliderAutomationPeer.cs
index 172b9a1b54..907e779046 100644
--- a/src/Avalonia.Controls/Automation/Peers/SliderAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/SliderAutomationPeer.cs
@@ -1,4 +1,3 @@
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class SliderAutomationPeer : RangeBaseAutomationPeer
{
- public SliderAutomationPeer(IAutomationNodeFactory factory, Slider owner)
- : base(factory, owner)
+ public SliderAutomationPeer(Slider owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/TabControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/TabControlAutomationPeer.cs
index d615be43f3..e14e61a6e4 100644
--- a/src/Avalonia.Controls/Automation/Peers/TabControlAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/TabControlAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class TabControlAutomationPeer : SelectingItemsControlAutomationPeer
{
- public TabControlAutomationPeer(IAutomationNodeFactory factory, TabControl owner)
- : base(factory, owner)
+ public TabControlAutomationPeer(TabControl owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/TabItemAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/TabItemAutomationPeer.cs
index 20021b5b96..dc794da915 100644
--- a/src/Avalonia.Controls/Automation/Peers/TabItemAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/TabItemAutomationPeer.cs
@@ -1,12 +1,11 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
namespace Avalonia.Automation.Peers
{
public class TabItemAutomationPeer : ListItemAutomationPeer
{
- public TabItemAutomationPeer(IAutomationNodeFactory factory, TabItem owner)
- : base(factory, owner)
+ public TabItemAutomationPeer(TabItem owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/TextBlockAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/TextBlockAutomationPeer.cs
index a2ddedffc6..37eaf6f7c0 100644
--- a/src/Avalonia.Controls/Automation/Peers/TextBlockAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/TextBlockAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Controls;
+using Avalonia.Controls;
#nullable enable
@@ -7,8 +6,8 @@ namespace Avalonia.Automation.Peers
{
public class TextBlockAutomationPeer : ControlAutomationPeer
{
- public TextBlockAutomationPeer(IAutomationNodeFactory factory, TextBlock owner)
- : base(factory, owner)
+ public TextBlockAutomationPeer(TextBlock owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/TextBoxAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/TextBoxAutomationPeer.cs
index 99f50ddabb..33b2ba58b6 100644
--- a/src/Avalonia.Controls/Automation/Peers/TextBoxAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/TextBoxAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Automation.Provider;
+using Avalonia.Automation.Provider;
using Avalonia.Controls;
#nullable enable
@@ -8,8 +7,8 @@ namespace Avalonia.Automation.Peers
{
public class TextBoxAutomationPeer : ControlAutomationPeer, IValueProvider
{
- public TextBoxAutomationPeer(IAutomationNodeFactory factory, TextBox owner)
- : base(factory, owner)
+ public TextBoxAutomationPeer(TextBox owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/ToggleButtonAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ToggleButtonAutomationPeer.cs
index 4c410d8654..dd0c506d29 100644
--- a/src/Avalonia.Controls/Automation/Peers/ToggleButtonAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/ToggleButtonAutomationPeer.cs
@@ -1,5 +1,4 @@
-using Avalonia.Automation.Platform;
-using Avalonia.Automation.Provider;
+using Avalonia.Automation.Provider;
using Avalonia.Controls.Primitives;
#nullable enable
@@ -8,8 +7,8 @@ namespace Avalonia.Automation.Peers
{
public class ToggleButtonAutomationPeer : ContentControlAutomationPeer, IToggleProvider
{
- public ToggleButtonAutomationPeer(IAutomationNodeFactory factory, ToggleButton owner)
- : base(factory, owner)
+ public ToggleButtonAutomationPeer(ToggleButton owner)
+ : base(owner)
{
}
diff --git a/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs
index 5832b04dd7..b388f21a17 100644
--- a/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/UnrealizedElementAutomationPeer.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using Avalonia.Automation.Platform;
#nullable enable
@@ -11,11 +10,6 @@ namespace Avalonia.Automation.Peers
///
public abstract class UnrealizedElementAutomationPeer : AutomationPeer
{
- protected UnrealizedElementAutomationPeer(IAutomationNodeFactory factory)
- : base(factory)
- {
- }
-
public void SetParent(AutomationPeer? parent) => TrySetParent(parent);
protected override void BringIntoViewCore() => GetParent()?.BringIntoView();
protected override Rect GetBoundingRectangleCore() => GetParent()?.GetBoundingRectangle() ?? default;
diff --git a/src/Avalonia.Controls/Automation/Peers/WindowAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/WindowAutomationPeer.cs
index 9629ae0294..fbc6e9d4f4 100644
--- a/src/Avalonia.Controls/Automation/Peers/WindowAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/WindowAutomationPeer.cs
@@ -1,5 +1,4 @@
using System;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
#nullable enable
@@ -8,8 +7,8 @@ namespace Avalonia.Automation.Peers
{
public class WindowAutomationPeer : WindowBaseAutomationPeer
{
- public WindowAutomationPeer(IAutomationNode node, Window owner)
- : base(node, owner)
+ public WindowAutomationPeer(Window owner)
+ : base(owner)
{
if (owner.IsVisible)
StartTrackingFocus();
diff --git a/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs
index f97d13c766..b24685929a 100644
--- a/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs
+++ b/src/Avalonia.Controls/Automation/Peers/WindowBaseAutomationPeer.cs
@@ -1,5 +1,5 @@
+using System;
using System.ComponentModel;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Avalonia.Input;
@@ -14,25 +14,27 @@ namespace Avalonia.Automation.Peers
{
private Control? _focus;
- public WindowBaseAutomationPeer(IAutomationNode node, WindowBase owner)
- : base(node, owner)
+ public WindowBaseAutomationPeer(WindowBase owner)
+ : base(owner)
{
}
public new WindowBase Owner => (WindowBase)base.Owner;
public ITopLevelImpl PlatformImpl => Owner.PlatformImpl;
+ public event EventHandler? FocusChanged;
+
protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Window;
}
- public AutomationPeer? GetFocus() => _focus is object ? GetOrCreatePeer(_focus) : null;
+ public AutomationPeer? GetFocus() => _focus is object ? GetOrCreate(_focus) : null;
public AutomationPeer? GetPeerFromPoint(Point p)
{
var hit = Owner.GetVisualAt(p)?.FindAncestorOfType(includeSelf: true);
- return hit is object ? GetOrCreatePeer(hit) : null;
+ return hit is object ? GetOrCreate(hit) : null;
}
protected void StartTrackingFocus()
@@ -54,8 +56,10 @@ namespace Avalonia.Automation.Peers
if (_focus != oldFocus)
{
- var peer = _focus is object ? GetOrCreatePeer(_focus) : null;
- ((IRootAutomationNode)Node).FocusChanged(peer);
+ var peer = _focus is object ?
+ _focus == Owner ? this :
+ GetOrCreate(_focus) : null;
+ FocusChanged?.Invoke(this, EventArgs.Empty);
}
}
diff --git a/src/Avalonia.Controls/Automation/Platform/IAutomationNode.cs b/src/Avalonia.Controls/Automation/Platform/IAutomationNode.cs
deleted file mode 100644
index cae3504a4a..0000000000
--- a/src/Avalonia.Controls/Automation/Platform/IAutomationNode.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using Avalonia.Automation.Peers;
-
-#nullable enable
-
-namespace Avalonia.Automation.Platform
-{
- ///
- /// Represents a platform implementation of a node in the UI Automation tree.
- ///
- public interface IAutomationNode
- {
- ///
- /// Gets a factory which can be used to create child nodes.
- ///
- IAutomationNodeFactory Factory { get; }
-
- ///
- /// Called by the when the children of the peer change.
- ///
- void ChildrenChanged();
-
- ///
- /// Called by the when a property other than the parent,
- /// children or root changes.
- ///
- /// The property that changed.
- /// The previous value of the property.
- /// The new value of the property.
- void PropertyChanged(AutomationProperty property, object? oldValue, object? newValue);
- }
-}
diff --git a/src/Avalonia.Controls/Automation/Platform/IAutomationNodeFactory.cs b/src/Avalonia.Controls/Automation/Platform/IAutomationNodeFactory.cs
deleted file mode 100644
index da16611b9e..0000000000
--- a/src/Avalonia.Controls/Automation/Platform/IAutomationNodeFactory.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Avalonia.Automation.Peers;
-
-#nullable enable
-
-namespace Avalonia.Automation.Platform
-{
- ///
- /// Creates nodes in the UI Automation tree of the underlying platform.
- ///
- public interface IAutomationNodeFactory
- {
- ///
- /// Creates an automation node for a peer.
- ///
- /// The peer.
- IAutomationNode CreateNode(AutomationPeer peer);
- }
-}
diff --git a/src/Avalonia.Controls/Automation/Platform/IRootAutomationNode.cs b/src/Avalonia.Controls/Automation/Platform/IRootAutomationNode.cs
deleted file mode 100644
index 8346a908c2..0000000000
--- a/src/Avalonia.Controls/Automation/Platform/IRootAutomationNode.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Avalonia.Automation.Peers;
-
-#nullable enable
-
-namespace Avalonia.Automation.Platform
-{
- ///
- /// Represents a platform implementation of a root node in the UI Automation tree.
- ///
- public interface IRootAutomationNode : IAutomationNode
- {
- ///
- /// Called by the when its focus changes.
- ///
- ///
- /// The automation peer for the newly focused control or null if no control is focused.
- ///
- void FocusChanged(AutomationPeer? focus);
- }
-}
diff --git a/src/Avalonia.Controls/Automation/Provider/IRootProvider.cs b/src/Avalonia.Controls/Automation/Provider/IRootProvider.cs
index 698b4f26b9..8ea53863eb 100644
--- a/src/Avalonia.Controls/Automation/Provider/IRootProvider.cs
+++ b/src/Avalonia.Controls/Automation/Provider/IRootProvider.cs
@@ -1,4 +1,5 @@
-using Avalonia.Automation.Peers;
+using System;
+using Avalonia.Automation.Peers;
using Avalonia.Platform;
#nullable enable
@@ -10,5 +11,6 @@ namespace Avalonia.Automation.Provider
ITopLevelImpl? PlatformImpl { get; }
AutomationPeer? GetFocus();
AutomationPeer? GetPeerFromPoint(Point p);
+ event EventHandler? FocusChanged;
}
}
diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs
index 645e697d03..740f715fe8 100644
--- a/src/Avalonia.Controls/Button.cs
+++ b/src/Avalonia.Controls/Button.cs
@@ -2,7 +2,6 @@ using System;
using System.Linq;
using System.Windows.Input;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
@@ -380,10 +379,7 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
- {
- return new ButtonAutomationPeer(factory, this);
- }
+ protected override AutomationPeer OnCreateAutomationPeer() => new ButtonAutomationPeer(this);
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValue value)
{
diff --git a/src/Avalonia.Controls/CheckBox.cs b/src/Avalonia.Controls/CheckBox.cs
index 374ab33338..f7b0dcfdc2 100644
--- a/src/Avalonia.Controls/CheckBox.cs
+++ b/src/Avalonia.Controls/CheckBox.cs
@@ -1,5 +1,4 @@
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Primitives;
namespace Avalonia.Controls
@@ -9,9 +8,9 @@ namespace Avalonia.Controls
///
public class CheckBox : ToggleButton
{
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new CheckBoxAutomationPeer(factory, this);
+ return new CheckBoxAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs
index a50132270b..70fb62dc69 100644
--- a/src/Avalonia.Controls/ComboBox.cs
+++ b/src/Avalonia.Controls/ComboBox.cs
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using System.Reactive.Disposables;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Mixins;
@@ -298,9 +297,9 @@ namespace Avalonia.Controls
_popup.Closed += PopupClosed;
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ComboBoxAutomationPeer(factory, this);
+ return new ComboBoxAutomationPeer(this);
}
internal void ItemFocused(ComboBoxItem dropDownItem)
diff --git a/src/Avalonia.Controls/ComboBoxItem.cs b/src/Avalonia.Controls/ComboBoxItem.cs
index 0d5846f270..42ec6e43b9 100644
--- a/src/Avalonia.Controls/ComboBoxItem.cs
+++ b/src/Avalonia.Controls/ComboBoxItem.cs
@@ -1,7 +1,6 @@
using System;
using System.Reactive.Linq;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
namespace Avalonia.Controls
{
@@ -16,9 +15,9 @@ namespace Avalonia.Controls
.Subscribe(_ => (Parent as ComboBox)?.ItemFocused(this));
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ComboBoxItemAutomationPeer(factory, this);
+ return new ComboBoxItemAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs
index ade23308d0..0a4b518f57 100644
--- a/src/Avalonia.Controls/ContextMenu.cs
+++ b/src/Avalonia.Controls/ContextMenu.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using System.Linq;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Generators;
@@ -320,9 +319,9 @@ namespace Avalonia.Controls
return new MenuItemContainerGenerator(this);
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ContextMenuAutomationPeer(factory, this);
+ return new ContextMenuAutomationPeer(this);
}
private void Open(Control control, Control placementTarget, bool requestedByPointer)
diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs
index 60acaf82db..a6b16a5b27 100644
--- a/src/Avalonia.Controls/Control.cs
+++ b/src/Avalonia.Controls/Control.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
@@ -230,12 +229,12 @@ namespace Avalonia.Controls
}
}
- protected virtual AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected virtual AutomationPeer OnCreateAutomationPeer()
{
- return new NoneAutomationPeer(factory, this);
+ return new NoneAutomationPeer(this);
}
- internal AutomationPeer GetOrCreateAutomationPeer(IAutomationNodeFactory factory)
+ internal AutomationPeer GetOrCreateAutomationPeer()
{
VerifyAccess();
@@ -244,17 +243,10 @@ namespace Avalonia.Controls
return _automationPeer;
}
- _automationPeer = OnCreateAutomationPeer(factory);
+ _automationPeer = OnCreateAutomationPeer();
return _automationPeer;
}
- internal void SetAutomationPeer(AutomationPeer peer)
- {
- if (_automationPeer is object)
- throw new InvalidOperationException("Automation peer is already set.");
- _automationPeer = peer ?? throw new ArgumentNullException(nameof(peer));
- }
-
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
diff --git a/src/Avalonia.Controls/Image.cs b/src/Avalonia.Controls/Image.cs
index ad5455ba06..aaf93cac26 100644
--- a/src/Avalonia.Controls/Image.cs
+++ b/src/Avalonia.Controls/Image.cs
@@ -1,5 +1,4 @@
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Metadata;
@@ -127,9 +126,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ImageAutomationPeer(factory, this);
+ return new ImageAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs
index dbf57b712d..e3bb7abaad 100644
--- a/src/Avalonia.Controls/ItemsControl.cs
+++ b/src/Avalonia.Controls/ItemsControl.cs
@@ -5,7 +5,6 @@ using System.Collections.Specialized;
using System.Linq;
using Avalonia.Collections;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
@@ -326,9 +325,9 @@ namespace Avalonia.Controls
base.OnKeyDown(e);
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ItemsControlAutomationPeer(factory, this);
+ return new ItemsControlAutomationPeer(this);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
diff --git a/src/Avalonia.Controls/ListBoxItem.cs b/src/Avalonia.Controls/ListBoxItem.cs
index 5599a89b62..66a46cab4a 100644
--- a/src/Avalonia.Controls/ListBoxItem.cs
+++ b/src/Avalonia.Controls/ListBoxItem.cs
@@ -1,5 +1,4 @@
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
@@ -36,9 +35,9 @@ namespace Avalonia.Controls
set { SetValue(IsSelectedProperty, value); }
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ListItemAutomationPeer(factory, this);
+ return new ListItemAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/Menu.cs b/src/Avalonia.Controls/Menu.cs
index d6a0dc6f12..ed70316a53 100644
--- a/src/Avalonia.Controls/Menu.cs
+++ b/src/Avalonia.Controls/Menu.cs
@@ -1,5 +1,4 @@
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
@@ -94,9 +93,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new MenuAutomationPeer(factory, this);
+ return new MenuAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs
index f773f8fe2a..8213cf29dc 100644
--- a/src/Avalonia.Controls/MenuItem.cs
+++ b/src/Avalonia.Controls/MenuItem.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Reactive.Linq;
using System.Windows.Input;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
@@ -495,9 +494,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new MenuItemAutomationPeer(factory, this);
+ return new MenuItemAutomationPeer(this);
}
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValue value)
diff --git a/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs b/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs
index 82b6f6666a..5a9e99106b 100644
--- a/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs
+++ b/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs
@@ -1,6 +1,5 @@
using System;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
namespace Avalonia.Platform
{
@@ -48,11 +47,6 @@ namespace Avalonia.Platform
///
Action Activated { get; set; }
- ///
- /// Gets or sets a method called when automation is started on the window.
- ///
- Func AutomationStarted { get; set; }
-
///
/// Gets the platform window handle.
///
diff --git a/src/Avalonia.Controls/Primitives/AccessText.cs b/src/Avalonia.Controls/Primitives/AccessText.cs
index 15c44e8c12..39f8cd938c 100644
--- a/src/Avalonia.Controls/Primitives/AccessText.cs
+++ b/src/Avalonia.Controls/Primitives/AccessText.cs
@@ -1,6 +1,5 @@
using System;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Media.TextFormatting;
@@ -108,9 +107,9 @@ namespace Avalonia.Controls.Primitives
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new NoneAutomationPeer(factory, this);
+ return new NoneAutomationPeer(this);
}
internal static string RemoveAccessKeyMarker(string text)
diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs
index ae72ccfee1..0bfbbf948b 100644
--- a/src/Avalonia.Controls/Primitives/Popup.cs
+++ b/src/Avalonia.Controls/Primitives/Popup.cs
@@ -3,7 +3,6 @@ using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Presenters;
@@ -543,9 +542,9 @@ namespace Avalonia.Controls.Primitives
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new PopupAutomationPeer(factory, this);
+ return new PopupAutomationPeer(this);
}
private static IDisposable SubscribeToEventHandler(T target, TEventHandler handler, Action subscribe, Action unsubscribe)
diff --git a/src/Avalonia.Controls/Primitives/PopupRoot.cs b/src/Avalonia.Controls/Primitives/PopupRoot.cs
index 0a0c0f30ad..f7281c107a 100644
--- a/src/Avalonia.Controls/Primitives/PopupRoot.cs
+++ b/src/Avalonia.Controls/Primitives/PopupRoot.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Interactivity;
using Avalonia.Media;
@@ -168,9 +167,9 @@ namespace Avalonia.Controls.Primitives
return ClientSize;
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNode node)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new PopupRootAutomationPeer(node, this);
+ return new PopupRootAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/Primitives/ToggleButton.cs b/src/Avalonia.Controls/Primitives/ToggleButton.cs
index 434d34928f..6c21302132 100644
--- a/src/Avalonia.Controls/Primitives/ToggleButton.cs
+++ b/src/Avalonia.Controls/Primitives/ToggleButton.cs
@@ -1,6 +1,5 @@
using System;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Metadata;
using Avalonia.Data;
using Avalonia.Interactivity;
@@ -171,9 +170,9 @@ namespace Avalonia.Controls.Primitives
RaiseEvent(e);
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ToggleButtonAutomationPeer(factory, this);
+ return new ToggleButtonAutomationPeer(this);
}
private void OnIsCheckedChanged(AvaloniaPropertyChangedEventArgs e)
diff --git a/src/Avalonia.Controls/ScrollViewer.cs b/src/Avalonia.Controls/ScrollViewer.cs
index 7d9675706c..eaa9ba43c3 100644
--- a/src/Avalonia.Controls/ScrollViewer.cs
+++ b/src/Avalonia.Controls/ScrollViewer.cs
@@ -1,7 +1,6 @@
using System;
using System.Reactive.Linq;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
@@ -712,9 +711,9 @@ namespace Avalonia.Controls
_scrollBarExpandSubscription = SubscribeToScrollBars(e);
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new ScrollViewerAutomationPeer(factory, this);
+ return new ScrollViewerAutomationPeer(this);
}
private IDisposable SubscribeToScrollBars(TemplateAppliedEventArgs e)
diff --git a/src/Avalonia.Controls/Slider.cs b/src/Avalonia.Controls/Slider.cs
index 698e1734bb..227c387ffb 100644
--- a/src/Avalonia.Controls/Slider.cs
+++ b/src/Avalonia.Controls/Slider.cs
@@ -1,7 +1,6 @@
using System;
using Avalonia.Collections;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Primitives;
@@ -211,9 +210,9 @@ namespace Avalonia.Controls
_pointerMovedDispose = this.AddDisposableHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel);
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new SliderAutomationPeer(factory, this);
+ return new SliderAutomationPeer(this);
}
protected override void OnKeyDown(KeyEventArgs e)
diff --git a/src/Avalonia.Controls/TabControl.cs b/src/Avalonia.Controls/TabControl.cs
index 63c68b783c..cc9dab986a 100644
--- a/src/Avalonia.Controls/TabControl.cs
+++ b/src/Avalonia.Controls/TabControl.cs
@@ -2,7 +2,6 @@ using System.ComponentModel;
using System.Linq;
using Avalonia.Collections;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
@@ -233,9 +232,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new TabControlAutomationPeer(factory, this);
+ return new TabControlAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/TabItem.cs b/src/Avalonia.Controls/TabItem.cs
index 90817c655d..846010ce77 100644
--- a/src/Avalonia.Controls/TabItem.cs
+++ b/src/Avalonia.Controls/TabItem.cs
@@ -1,5 +1,4 @@
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Primitives;
@@ -83,9 +82,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new TabItemAutomationPeer(factory, this);
+ return new TabItemAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index 8b4af15bc8..27db48e3f4 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -1,6 +1,5 @@
using System.Reactive.Linq;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Media;
@@ -513,9 +512,9 @@ namespace Avalonia.Controls
InvalidateMeasure();
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new TextBlockAutomationPeer(factory, this);
+ return new TextBlockAutomationPeer(this);
}
private static bool IsValidMaxLines(int maxLines) => maxLines >= 0;
diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index f28d792dc2..5b334d2029 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -15,7 +15,6 @@ using Avalonia.Layout;
using Avalonia.Utilities;
using Avalonia.Controls.Metadata;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
namespace Avalonia.Controls
{
@@ -1055,9 +1054,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new TextBoxAutomationPeer(factory, this);
+ return new TextBoxAutomationPeer(this);
}
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValue value)
diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs
index a8e76a394b..5d9a0c8eed 100644
--- a/src/Avalonia.Controls/TopLevel.cs
+++ b/src/Avalonia.Controls/TopLevel.cs
@@ -1,7 +1,5 @@
using System;
using System.Reactive.Linq;
-using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index bbb0c16450..50227445df 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -5,7 +5,6 @@ using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Interactivity;
@@ -1014,9 +1013,9 @@ namespace Avalonia.Controls
}
}
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNode node)
+ protected override AutomationPeer OnCreateAutomationPeer()
{
- return new WindowAutomationPeer(node, this);
+ return new WindowAutomationPeer(this);
}
}
}
diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs
index 905a6b552f..a3fd584447 100644
--- a/src/Avalonia.Controls/WindowBase.cs
+++ b/src/Avalonia.Controls/WindowBase.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Layout;
@@ -65,7 +64,6 @@ namespace Avalonia.Controls
impl.Activated = HandleActivated;
impl.Deactivated = HandleDeactivated;
impl.PositionChanged = HandlePositionChanged;
- impl.AutomationStarted = HandleAutomationStarted;
}
///
@@ -263,17 +261,6 @@ namespace Avalonia.Controls
/// The actual size of the window.
protected virtual Size ArrangeSetBounds(Size size) => size;
- protected sealed override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
- {
- throw new NotSupportedException(
- "Automation peer for window controls must be created by the operating system.");
- }
-
- protected virtual AutomationPeer OnCreateAutomationPeer(IAutomationNode node)
- {
- throw new NotImplementedException("OnCreateAutomationPeer must be implemented in a derived class.");
- }
-
///
/// Handles a window position change notification from
/// .
@@ -311,13 +298,6 @@ namespace Avalonia.Controls
Deactivated?.Invoke(this, EventArgs.Empty);
}
- private AutomationPeer HandleAutomationStarted(IAutomationNode node)
- {
- var peer = OnCreateAutomationPeer(node);
- SetAutomationPeer(peer);
- return peer;
- }
-
private void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e)
{
if (!_ignoreVisibilityChange)
diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
index ec685191d1..12af602f54 100644
--- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
+++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
@@ -1,7 +1,4 @@
using System;
-using System.Reactive.Disposables;
-using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Remote.Server;
using Avalonia.Input;
@@ -47,7 +44,6 @@ namespace Avalonia.DesignerSupport.Remote
public IPlatformHandle Handle { get; }
public WindowState WindowState { get; set; }
public Action WindowStateChanged { get; set; }
- public Func AutomationStarted { get; set; }
public Size MaxAutoSizeHint { get; } = new Size(4096, 4096);
protected override void OnMessage(IAvaloniaRemoteTransportConnection transport, object obj)
diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs
index a8e0ddad52..8fb2c456b2 100644
--- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs
+++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs
@@ -4,7 +4,6 @@ using System.IO;
using System.Reactive.Disposables;
using System.Threading.Tasks;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives.PopupPositioning;
@@ -41,7 +40,6 @@ namespace Avalonia.DesignerSupport.Remote
public Action PositionChanged { get; set; }
public WindowState WindowState { get; set; }
public Action WindowStateChanged { get; set; }
- public Func AutomationStarted { get; set; }
public Action TransparencyLevelChanged { get; set; }
diff --git a/src/Avalonia.Headless/HeadlessWindowImpl.cs b/src/Avalonia.Headless/HeadlessWindowImpl.cs
index 55a1476933..3bf7db34f6 100644
--- a/src/Avalonia.Headless/HeadlessWindowImpl.cs
+++ b/src/Avalonia.Headless/HeadlessWindowImpl.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Controls.Primitives.PopupPositioning;
@@ -145,7 +144,6 @@ namespace Avalonia.Headless
public IScreenImpl Screen { get; } = new HeadlessScreensStub();
public WindowState WindowState { get; set; }
public Action WindowStateChanged { get; set; }
- public Func AutomationStarted { get; set; }
public void SetTitle(string title)
{
diff --git a/src/Avalonia.Native/AutomationNode.cs b/src/Avalonia.Native/AutomationNode.cs
index f85813a6fb..251b7156f1 100644
--- a/src/Avalonia.Native/AutomationNode.cs
+++ b/src/Avalonia.Native/AutomationNode.cs
@@ -1,22 +1,19 @@
using Avalonia.Automation;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Native.Interop;
#nullable enable
namespace Avalonia.Native
{
- internal class AutomationNode : IRootAutomationNode
+ internal class AutomationNode
{
- public AutomationNode(AutomationNodeFactory factory, IAvnAutomationNode native)
+ public AutomationNode(IAvnAutomationNode native)
{
Native = native;
- Factory = factory;
}
public IAvnAutomationNode Native { get; }
- public IAutomationNodeFactory Factory { get; }
public void ChildrenChanged() => Native.ChildrenChanged();
diff --git a/src/Avalonia.Native/AutomationNodeFactory.cs b/src/Avalonia.Native/AutomationNodeFactory.cs
deleted file mode 100644
index d40009a855..0000000000
--- a/src/Avalonia.Native/AutomationNodeFactory.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
-using Avalonia.Native.Interop;
-
-namespace Avalonia.Native
-{
- internal class AutomationNodeFactory : IAutomationNodeFactory
- {
- private static AutomationNodeFactory _instance;
- private readonly IAvaloniaNativeFactory _native;
-
- public static AutomationNodeFactory GetInstance(IAvaloniaNativeFactory native)
- {
- return _instance ??= new AutomationNodeFactory(native);
- }
-
- private AutomationNodeFactory(IAvaloniaNativeFactory native) => _native = native;
-
- public IAutomationNode CreateNode(AutomationPeer peer)
- {
- return new AutomationNode(this, _native.CreateAutomationNode(new AvnAutomationPeer(peer)));
- }
- }
-}
diff --git a/src/Avalonia.Native/AvnAutomationPeer.cs b/src/Avalonia.Native/AvnAutomationPeer.cs
index dee7658d33..b50b0d5111 100644
--- a/src/Avalonia.Native/AvnAutomationPeer.cs
+++ b/src/Avalonia.Native/AvnAutomationPeer.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Automation;
@@ -15,7 +16,7 @@ namespace Avalonia.Native
public AvnAutomationPeer(AutomationPeer inner) => _inner = inner;
- public IAvnAutomationNode Node => ((AutomationNode)_inner.Node).Native;
+ public IAvnAutomationNode Node => throw new NotImplementedException();
public IAvnString? AcceleratorKey => _inner.GetAcceleratorKey().ToAvnString();
public IAvnString? AccessKey => _inner.GetAccessKey().ToAvnString();
public AvnAutomationControlType AutomationControlType => (AvnAutomationControlType)_inner.GetAutomationControlType();
diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs
index 529e90ab49..d055e4a1c4 100644
--- a/src/Avalonia.Native/WindowImplBase.cs
+++ b/src/Avalonia.Native/WindowImplBase.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Platform.Surfaces;
@@ -63,9 +62,7 @@ namespace Avalonia.Native
private GlPlatformSurface _glSurface;
private NativeControlHostImpl _nativeControlHost;
private IGlContext _glContext;
- private IAutomationNode _automationNode;
private AvnAutomationPeer _automationPeer;
- private Func _automationStarted;
internal WindowBaseImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts,
AvaloniaNativePlatformOpenGlInterface glFeature)
@@ -265,8 +262,6 @@ namespace Avalonia.Native
return (AvnDragDropEffects)args.Effects;
}
}
-
- public IAvnAutomationPeer AutomationStarted(IAvnAutomationNode node) => _parent.HandleAutomationStarted(node);
}
public void Activate()
@@ -489,38 +484,5 @@ namespace Avalonia.Native
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0, 0);
public IPlatformHandle Handle { get; private set; }
-
- public Func AutomationStarted
- {
- get => _automationStarted;
- set
- {
- _automationStarted = value;
-
- // We've already received an AutomationStarted event, but the Window/PopupRoot wasn't initialized.
- // Now it is, so notify it and store the automation peer for the next time the OS invokes an a11y
- // query.
- if (value is object && _automationNode is object)
- _automationPeer = new AvnAutomationPeer(_automationStarted.Invoke(_automationNode));
- }
- }
-
- private AvnAutomationPeer HandleAutomationStarted(IAvnAutomationNode node)
- {
- if (_automationPeer is object)
- return _automationPeer;
-
- var factory = AutomationNodeFactory.GetInstance(_factory);
- _automationNode = new AutomationNode(factory, node);
-
- // If automation is started during platform window creation we don't yet have a Window/PopupRoot
- // control to notify. In this case we'll notify them when AutomationStarted gets set. We can safely
- // return null here because the peer isn't actually needed at this point and will be re-queried the next
- // time it's needed.
- if (AutomationStarted is null)
- return null;
-
- return _automationPeer = new AvnAutomationPeer(AutomationStarted(_automationNode));
- }
}
}
diff --git a/src/Avalonia.Native/avn.idl b/src/Avalonia.Native/avn.idl
index da1bd7decd..3aec9d493c 100644
--- a/src/Avalonia.Native/avn.idl
+++ b/src/Avalonia.Native/avn.idl
@@ -569,7 +569,6 @@ interface IAvnWindowBaseEvents : IUnknown
AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
AvnInputModifiers modifiers, AvnDragDropEffects effects,
IAvnClipboard* clipboard, [intptr]void* dataObjectHandle);
- IAvnAutomationPeer* AutomationStarted(IAvnAutomationNode* node);
}
[uuid(1ae178ee-1fcc-447f-b6dd-b7bb727f934c)]
diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs
index 6783eada1f..938a7f9b5d 100644
--- a/src/Avalonia.X11/X11Window.cs
+++ b/src/Avalonia.X11/X11Window.cs
@@ -7,7 +7,6 @@ using System.Reactive.Disposables;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives.PopupPositioning;
@@ -1163,6 +1162,5 @@ namespace Avalonia.X11
public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0.8, 0.8);
public bool NeedsManagedDecorations => false;
- public Func AutomationStarted { get; set; }
}
}
diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs
index 17634ae805..c41ace4aa8 100644
--- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs
+++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs
@@ -20,14 +20,14 @@ namespace Avalonia.Win32.Automation
get
{
var peer = InvokeSync(x => x.SelectionContainer);
- return (peer as AutomationPeer)?.Node as AutomationNode;
+ return GetOrCreate(peer as AutomationPeer);
}
}
public UIA.IRawElementProviderSimple[] GetSelection()
{
var peers = InvokeSync>(x => x.GetSelection());
- return peers?.Select(x => (UIA.IRawElementProviderSimple)x.Node).ToArray() ??
+ return peers?.Select(x => (UIA.IRawElementProviderSimple)GetOrCreate(x)!).ToArray() ??
Array.Empty();
}
diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs
index 79ef5bc719..ebaf096b78 100644
--- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs
+++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs
@@ -4,10 +4,10 @@ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Avalonia.Automation;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Threading;
using Avalonia.Win32.Interop.Automation;
using AAP = Avalonia.Automation.Provider;
@@ -18,7 +18,6 @@ namespace Avalonia.Win32.Automation
{
[ComVisible(true)]
internal partial class AutomationNode : MarshalByRefObject,
- IAutomationNode,
IRawElementProviderSimple,
IRawElementProviderSimple2,
IRawElementProviderFragment,
@@ -46,6 +45,9 @@ namespace Avalonia.Win32.Automation
{ SelectionPatternIdentifiers.SelectionProperty, UiaPropertyId.SelectionSelection },
};
+ private static ConditionalWeakTable s_nodes =
+ new ConditionalWeakTable();
+
private readonly int[] _runtimeId;
private int _raiseFocusChanged;
private int _raisePropertyChanged;
@@ -54,22 +56,16 @@ namespace Avalonia.Win32.Automation
{
_runtimeId = new int[] { 3, GetHashCode() };
Peer = peer;
- }
-
- protected AutomationNode(Func peerGetter)
- {
- _runtimeId = new int[] { 3, GetHashCode() };
- Peer = peerGetter(this);
+ s_nodes.Add(peer, this);
}
public AutomationPeer Peer { get; protected set; }
- public IAutomationNodeFactory Factory => AutomationNodeFactory.Instance;
public Rect BoundingRectangle
{
get => InvokeSync(() =>
{
- if (GetRoot()?.Node is RootAutomationNode root)
+ if (GetRoot() is RootAutomationNode root)
return root.ToScreen(Peer.GetBoundingRectangle());
return default;
});
@@ -77,7 +73,7 @@ namespace Avalonia.Win32.Automation
public virtual IRawElementProviderFragmentRoot? FragmentRoot
{
- get => InvokeSync(() => GetRoot())?.Node as IRawElementProviderFragmentRoot;
+ get => InvokeSync(() => GetRoot()) as IRawElementProviderFragmentRoot;
}
public virtual IRawElementProviderSimple? HostRawElementProvider => null;
@@ -147,7 +143,7 @@ namespace Avalonia.Win32.Automation
public virtual IRawElementProviderFragment? Navigate(NavigateDirection direction)
{
- IAutomationNode? GetSibling(int direction)
+ AutomationNode? GetSibling(int direction)
{
var children = Peer.GetParent()?.GetChildren();
@@ -157,7 +153,7 @@ namespace Avalonia.Win32.Automation
{
var j = i + direction;
if (j >= 0 && j < children.Count)
- return children[j].Node;
+ return GetOrCreate(children[j]);
}
}
@@ -173,11 +169,11 @@ namespace Avalonia.Win32.Automation
{
return direction switch
{
- NavigateDirection.Parent => Peer.GetParent()?.Node,
+ NavigateDirection.Parent => GetOrCreate(Peer.GetParent()),
NavigateDirection.NextSibling => GetSibling(1),
NavigateDirection.PreviousSibling => GetSibling(-1),
- NavigateDirection.FirstChild => Peer.GetChildren().FirstOrDefault()?.Node,
- NavigateDirection.LastChild => Peer.GetChildren().LastOrDefault()?.Node,
+ NavigateDirection.FirstChild => GetOrCreate(Peer.GetChildren().FirstOrDefault()),
+ NavigateDirection.LastChild => GetOrCreate(Peer.GetChildren().LastOrDefault()),
_ => null,
};
}) as IRawElementProviderFragment;
@@ -185,6 +181,13 @@ namespace Avalonia.Win32.Automation
public void SetFocus() => InvokeSync(() => Peer.SetFocus());
+ public static AutomationNode? GetOrCreate(AutomationPeer? peer)
+ {
+ if (peer is null)
+ return null;
+ return s_nodes.GetValue(peer, x => new AutomationNode(x));
+ }
+
IRawElementProviderSimple[]? IRawElementProviderFragment.GetEmbeddedFragmentRoots() => null;
void IRawElementProviderSimple2.ShowContextMenu() => InvokeSync(() => Peer.ShowContextMenu());
void IInvokeProvider.Invoke() => InvokeSync((AAP.IInvokeProvider x) => x.Invoke());
@@ -275,7 +278,7 @@ namespace Avalonia.Win32.Automation
}
}
- private AutomationPeer GetRoot()
+ private AutomationNode? GetRoot()
{
Dispatcher.UIThread.VerifyAccess();
@@ -288,7 +291,7 @@ namespace Avalonia.Win32.Automation
parent = peer.GetParent();
}
- return peer;
+ return peer is object ? GetOrCreate(peer) : null;
}
private static UiaControlTypeId ToUiaControlType(AutomationControlType role)
diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNodeFactory.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNodeFactory.cs
deleted file mode 100644
index a7ee0e192f..0000000000
--- a/src/Windows/Avalonia.Win32/Automation/AutomationNodeFactory.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
-using Avalonia.Threading;
-
-#nullable enable
-
-namespace Avalonia.Win32.Automation
-{
- internal class AutomationNodeFactory : IAutomationNodeFactory
- {
- public static readonly AutomationNodeFactory Instance = new AutomationNodeFactory();
-
- public IAutomationNode CreateNode(AutomationPeer peer)
- {
- Dispatcher.UIThread.VerifyAccess();
- return new AutomationNode(peer);
- }
- }
-}
diff --git a/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs b/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs
index dd2665a624..6728aa4283 100644
--- a/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs
+++ b/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs
@@ -1,7 +1,6 @@
using System;
using System.Runtime.InteropServices;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Automation.Provider;
using Avalonia.Win32.Interop.Automation;
@@ -10,12 +9,12 @@ using Avalonia.Win32.Interop.Automation;
namespace Avalonia.Win32.Automation
{
internal class RootAutomationNode : AutomationNode,
- IRawElementProviderFragmentRoot,
- IRootAutomationNode
+ IRawElementProviderFragmentRoot
{
- public RootAutomationNode(Func peerGetter)
- : base(peerGetter)
+ public RootAutomationNode(AutomationPeer peer)
+ : base(peer)
{
+ ((IRootProvider)peer).FocusChanged += FocusChanged;
}
public override IRawElementProviderFragmentRoot? FragmentRoot => this;
@@ -30,20 +29,19 @@ namespace Avalonia.Win32.Automation
var p = WindowImpl.PointToClient(new PixelPoint((int)x, (int)y));
var peer = (WindowBaseAutomationPeer)Peer;
var found = InvokeSync(() => peer.GetPeerFromPoint(p));
- var result = found?.Node as IRawElementProviderFragment;
+ var result = GetOrCreate(found) as IRawElementProviderFragment;
return result;
}
public IRawElementProviderFragment? GetFocus()
{
var focus = InvokeSync(() => Peer.GetFocus());
- return (AutomationNode?)focus?.Node;
+ return GetOrCreate(focus);
}
- public void FocusChanged(AutomationPeer? focus)
+ public void FocusChanged(object sender, EventArgs e)
{
- var node = focus?.Node as AutomationNode;
- RaiseFocusChanged(node);
+ RaiseFocusChanged(GetOrCreate(Peer.GetFocus()));
}
public Rect ToScreen(Rect rect)
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
index 8803901bc5..fcc0ac1e32 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
+using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Controls.Remote;
using Avalonia.Input;
@@ -483,16 +484,14 @@ namespace Avalonia.Win32
case WindowsMessage.WM_GETOBJECT:
if ((long)lParam == UiaRootObjectId)
{
- if (_automationNode is null && AutomationStarted is object)
+ if (_automationNode is null)
{
- _automationNode = new RootAutomationNode(AutomationStarted);
+ var peer = ControlAutomationPeer.CreatePeerForElement((Control)_owner);
+ _automationNode = new RootAutomationNode(peer);
}
- if (_automationNode is object)
- {
- var r = UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, wParam, lParam, _automationNode);
- return r;
- }
+ var r = UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, wParam, lParam, _automationNode);
+ return r;
}
break;
}
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index 24bf409f58..ffad00cf95 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -4,7 +4,6 @@ using System.ComponentModel;
using System.Runtime.InteropServices;
using Avalonia.Controls;
using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Raw;
@@ -177,7 +176,6 @@ namespace Avalonia.Win32
public Action LostFocus { get; set; }
public Action TransparencyLevelChanged { get; set; }
- public Func AutomationStarted { get; set; }
public Thickness BorderThickness
{
diff --git a/tests/Avalonia.Controls.UnitTests/Automation/ControlAutomationPeerTests.cs b/tests/Avalonia.Controls.UnitTests/Automation/ControlAutomationPeerTests.cs
index 250cad4e25..3a4bbd9928 100644
--- a/tests/Avalonia.Controls.UnitTests/Automation/ControlAutomationPeerTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/Automation/ControlAutomationPeerTests.cs
@@ -1,253 +1,253 @@
-using System.Linq;
-using Avalonia.Automation.Peers;
-using Avalonia.Automation.Platform;
-using Avalonia.Automation.Provider;
-using Avalonia.Controls.Presenters;
-using Avalonia.Controls.Primitives;
-using Avalonia.Controls.Templates;
-using Avalonia.Platform;
-using Avalonia.UnitTests;
-using Avalonia.VisualTree;
-using Moq;
-using Xunit;
-
-namespace Avalonia.Controls.UnitTests.Automation
-{
- public class ControlAutomationPeerTests
- {
- private static Mock _factory;
-
- public ControlAutomationPeerTests()
- {
- _factory = new Mock();
- _factory.Setup(x => x.CreateNode(It.IsAny()))
- .Returns(() => Mock.Of(x => x.Factory == _factory));
- }
-
- public class Children
- {
- [Fact]
- public void Creates_Children_For_Controls_In_Visual_Tree()
- {
- var panel = new Panel
- {
- Children =
- {
- new Border(),
- new Border(),
- },
- };
-
- var factory = CreateFactory();
- var target = CreatePeer(factory, panel);
-
- Assert.Equal(
- panel.GetVisualChildren(),
- target.GetChildren().Cast().Select(x => x.Owner));
- }
-
- [Fact]
- public void Creates_Children_when_Controls_Attached_To_Visual_Tree()
- {
- var contentControl = new ContentControl
- {
- Template = new FuncControlTemplate((o, ns) =>
- new ContentPresenter
- {
- Name = "PART_ContentPresenter",
- [!ContentPresenter.ContentProperty] = o[!ContentControl.ContentProperty],
- }),
- Content = new Border(),
- };
-
- var factory = CreateFactory();
- var target = CreatePeer(factory, contentControl);
-
- Assert.Empty(target.GetChildren());
-
- contentControl.Measure(Size.Infinity);
-
- Assert.Equal(1, target.GetChildren().Count);
- }
-
- [Fact]
- public void Updates_Children_When_VisualChildren_Added()
- {
- var panel = new Panel
- {
- Children =
- {
- new Border(),
- new Border(),
- },
- };
-
- var factory = CreateFactory();
- var target = CreatePeer(factory, panel);
- var children = target.GetChildren();
-
- Assert.Equal(2, children.Count);
-
- panel.Children.Add(new Decorator());
-
- children = target.GetChildren();
- Assert.Equal(3, children.Count);
- }
-
- [Fact]
- public void Updates_Children_When_VisualChildren_Removed()
- {
- var panel = new Panel
- {
- Children =
- {
- new Border(),
- new Border(),
- },
- };
-
- var factory = CreateFactory();
- var target = CreatePeer(factory, panel);
- var children = target.GetChildren();
-
- Assert.Equal(2, children.Count);
-
- panel.Children.RemoveAt(1);
-
- children = target.GetChildren();
- Assert.Equal(1, children.Count);
- }
-
- [Fact]
- public void Updates_Children_When_Visibility_Changes()
- {
- var panel = new Panel
- {
- Children =
- {
- new Border(),
- new Border(),
- },
- };
-
- var factory = CreateFactory();
- var target = CreatePeer(factory, panel);
- var children = target.GetChildren();
-
- Assert.Equal(2, children.Count);
-
- panel.Children[1].IsVisible = false;
- children = target.GetChildren();
- Assert.Equal(1, children.Count);
-
- panel.Children[1].IsVisible = true;
- children = target.GetChildren();
- Assert.Equal(2, children.Count);
- }
- }
-
- public class Parent
- {
- [Fact]
- public void Connects_Peer_To_Tree_When_GetParent_Called()
- {
- var border = new Border();
- var tree = new Decorator
- {
- Child = new Decorator
- {
- Child = border,
- }
- };
-
- var factory = CreateFactory();
-
- // We're accessing Border directly without going via its ancestors. Because the tree
- // is built lazily, ensure that calling GetParent causes the ancestor tree to be built.
- var target = CreatePeer(factory, border);
-
- var parentPeer = Assert.IsAssignableFrom(target.GetParent());
- Assert.Same(border.GetVisualParent(), parentPeer.Owner);
- }
-
- [Fact]
- public void Parent_Updated_When_Moved_To_Separate_Visual_Tree()
- {
- var border = new Border();
- var root1 = new Decorator { Child = border };
- var root2 = new Decorator();
- var factory = CreateFactory();
- var target = CreatePeer(factory, border);
-
- var parentPeer = Assert.IsAssignableFrom(target.GetParent());
- Assert.Same(root1, parentPeer.Owner);
-
- root1.Child = null;
-
- Assert.Null(target.GetParent());
-
- root2.Child = border;
-
- parentPeer = Assert.IsAssignableFrom(target.GetParent());
- Assert.Same(root2, parentPeer.Owner);
- }
- }
-
- private static IAutomationNodeFactory CreateFactory()
- {
- var factory = new Mock();
- factory.Setup(x => x.CreateNode(It.IsAny()))
- .Returns(() => Mock.Of(x => x.Factory == factory.Object));
- return factory.Object;
- }
-
- private static AutomationPeer CreatePeer(IAutomationNodeFactory factory, Control control)
- {
- return ControlAutomationPeer.GetOrCreatePeer(factory, control);
- }
-
- private class TestControl : Control
- {
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
- {
- return new TestAutomationPeer(factory, this);
- }
- }
-
- private class AutomationTestRoot : TestRoot
- {
- protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
- {
- return new TestRootAutomationPeer(factory, this);
- }
- }
-
- private class TestAutomationPeer : ControlAutomationPeer
- {
- public TestAutomationPeer(IAutomationNodeFactory factory, Control owner)
- : base(factory, owner)
- {
- }
- }
-
- private class TestRootAutomationPeer : ControlAutomationPeer, IRootProvider
- {
- public TestRootAutomationPeer(IAutomationNodeFactory factory, Control owner)
- : base(factory, owner)
- {
- }
-
- public ITopLevelImpl PlatformImpl => throw new System.NotImplementedException();
-
- public AutomationPeer GetFocus()
- {
- throw new System.NotImplementedException();
- }
-
- public AutomationPeer GetPeerFromPoint(Point p)
- {
- throw new System.NotImplementedException();
- }
- }
- }
-}
+////using System.Linq;
+////using Avalonia.Automation.Peers;
+////using Avalonia.Automation.Platform;
+////using Avalonia.Automation.Provider;
+////using Avalonia.Controls.Presenters;
+////using Avalonia.Controls.Primitives;
+////using Avalonia.Controls.Templates;
+////using Avalonia.Platform;
+////using Avalonia.UnitTests;
+////using Avalonia.VisualTree;
+////using Moq;
+////using Xunit;
+
+////namespace Avalonia.Controls.UnitTests.Automation
+////{
+//// public class ControlAutomationPeerTests
+//// {
+//// private static Mock _factory;
+
+//// public ControlAutomationPeerTests()
+//// {
+//// _factory = new Mock();
+//// _factory.Setup(x => x.CreateNode(It.IsAny()))
+//// .Returns(() => Mock.Of(x => x.Factory == _factory));
+//// }
+
+//// public class Children
+//// {
+//// [Fact]
+//// public void Creates_Children_For_Controls_In_Visual_Tree()
+//// {
+//// var panel = new Panel
+//// {
+//// Children =
+//// {
+//// new Border(),
+//// new Border(),
+//// },
+//// };
+
+//// var factory = CreateFactory();
+//// var target = CreatePeer(factory, panel);
+
+//// Assert.Equal(
+//// panel.GetVisualChildren(),
+//// target.GetChildren().Cast().Select(x => x.Owner));
+//// }
+
+//// [Fact]
+//// public void Creates_Children_when_Controls_Attached_To_Visual_Tree()
+//// {
+//// var contentControl = new ContentControl
+//// {
+//// Template = new FuncControlTemplate((o, ns) =>
+//// new ContentPresenter
+//// {
+//// Name = "PART_ContentPresenter",
+//// [!ContentPresenter.ContentProperty] = o[!ContentControl.ContentProperty],
+//// }),
+//// Content = new Border(),
+//// };
+
+//// var factory = CreateFactory();
+//// var target = CreatePeer(factory, contentControl);
+
+//// Assert.Empty(target.GetChildren());
+
+//// contentControl.Measure(Size.Infinity);
+
+//// Assert.Equal(1, target.GetChildren().Count);
+//// }
+
+//// [Fact]
+//// public void Updates_Children_When_VisualChildren_Added()
+//// {
+//// var panel = new Panel
+//// {
+//// Children =
+//// {
+//// new Border(),
+//// new Border(),
+//// },
+//// };
+
+//// var factory = CreateFactory();
+//// var target = CreatePeer(factory, panel);
+//// var children = target.GetChildren();
+
+//// Assert.Equal(2, children.Count);
+
+//// panel.Children.Add(new Decorator());
+
+//// children = target.GetChildren();
+//// Assert.Equal(3, children.Count);
+//// }
+
+//// [Fact]
+//// public void Updates_Children_When_VisualChildren_Removed()
+//// {
+//// var panel = new Panel
+//// {
+//// Children =
+//// {
+//// new Border(),
+//// new Border(),
+//// },
+//// };
+
+//// var factory = CreateFactory();
+//// var target = CreatePeer(factory, panel);
+//// var children = target.GetChildren();
+
+//// Assert.Equal(2, children.Count);
+
+//// panel.Children.RemoveAt(1);
+
+//// children = target.GetChildren();
+//// Assert.Equal(1, children.Count);
+//// }
+
+//// [Fact]
+//// public void Updates_Children_When_Visibility_Changes()
+//// {
+//// var panel = new Panel
+//// {
+//// Children =
+//// {
+//// new Border(),
+//// new Border(),
+//// },
+//// };
+
+//// var factory = CreateFactory();
+//// var target = CreatePeer(factory, panel);
+//// var children = target.GetChildren();
+
+//// Assert.Equal(2, children.Count);
+
+//// panel.Children[1].IsVisible = false;
+//// children = target.GetChildren();
+//// Assert.Equal(1, children.Count);
+
+//// panel.Children[1].IsVisible = true;
+//// children = target.GetChildren();
+//// Assert.Equal(2, children.Count);
+//// }
+//// }
+
+//// public class Parent
+//// {
+//// [Fact]
+//// public void Connects_Peer_To_Tree_When_GetParent_Called()
+//// {
+//// var border = new Border();
+//// var tree = new Decorator
+//// {
+//// Child = new Decorator
+//// {
+//// Child = border,
+//// }
+//// };
+
+//// var factory = CreateFactory();
+
+//// // We're accessing Border directly without going via its ancestors. Because the tree
+//// // is built lazily, ensure that calling GetParent causes the ancestor tree to be built.
+//// var target = CreatePeer(factory, border);
+
+//// var parentPeer = Assert.IsAssignableFrom(target.GetParent());
+//// Assert.Same(border.GetVisualParent(), parentPeer.Owner);
+//// }
+
+//// [Fact]
+//// public void Parent_Updated_When_Moved_To_Separate_Visual_Tree()
+//// {
+//// var border = new Border();
+//// var root1 = new Decorator { Child = border };
+//// var root2 = new Decorator();
+//// var factory = CreateFactory();
+//// var target = CreatePeer(factory, border);
+
+//// var parentPeer = Assert.IsAssignableFrom(target.GetParent());
+//// Assert.Same(root1, parentPeer.Owner);
+
+//// root1.Child = null;
+
+//// Assert.Null(target.GetParent());
+
+//// root2.Child = border;
+
+//// parentPeer = Assert.IsAssignableFrom(target.GetParent());
+//// Assert.Same(root2, parentPeer.Owner);
+//// }
+//// }
+
+//// private static IAutomationNodeFactory CreateFactory()
+//// {
+//// var factory = new Mock();
+//// factory.Setup(x => x.CreateNode(It.IsAny()))
+//// .Returns(() => Mock.Of(x => x.Factory == factory.Object));
+//// return factory.Object;
+//// }
+
+//// private static AutomationPeer CreatePeer(IAutomationNodeFactory factory, Control control)
+//// {
+//// return ControlAutomationPeer.GetOrCreatePeer(factory, control);
+//// }
+
+//// private class TestControl : Control
+//// {
+//// protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+//// {
+//// return new TestAutomationPeer(factory, this);
+//// }
+//// }
+
+//// private class AutomationTestRoot : TestRoot
+//// {
+//// protected override AutomationPeer OnCreateAutomationPeer(IAutomationNodeFactory factory)
+//// {
+//// return new TestRootAutomationPeer(factory, this);
+//// }
+//// }
+
+//// private class TestAutomationPeer : ControlAutomationPeer
+//// {
+//// public TestAutomationPeer(IAutomationNodeFactory factory, Control owner)
+//// : base(factory, owner)
+//// {
+//// }
+//// }
+
+//// private class TestRootAutomationPeer : ControlAutomationPeer, IRootProvider
+//// {
+//// public TestRootAutomationPeer(IAutomationNodeFactory factory, Control owner)
+//// : base(factory, owner)
+//// {
+//// }
+
+//// public ITopLevelImpl PlatformImpl => throw new System.NotImplementedException();
+
+//// public AutomationPeer GetFocus()
+//// {
+//// throw new System.NotImplementedException();
+//// }
+
+//// public AutomationPeer GetPeerFromPoint(Point p)
+//// {
+//// throw new System.NotImplementedException();
+//// }
+//// }
+//// }
+////}