From 78bd90ddaeb3e96f6396069b1fca258c1e3f5362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Sat, 30 Mar 2024 08:49:30 +0100 Subject: [PATCH] Add basic support for automation for DataGrid and DataGridRow (#15174) * Add basic support for automation for DataGrid and DataGridRow * Add DataGridCellAutomationPeer * Add DataGridColumnHeaderAutomationPeer * Add DataGridColumnHeadersPresenterAutomationPeer * Add DataGridDetailsPresenterAutomationPeer --- .../Peers/DataGridAutomationPeer.cs | 18 +++++++++++++++ .../Peers/DataGridCellAutomationPeer.cs | 22 ++++++++++++++++++ .../DataGridColumnHeaderAutomationPeer.cs | 22 ++++++++++++++++++ ...ridColumnHeadersPresenterAutomationPeer.cs | 23 +++++++++++++++++++ .../DataGridDetailsPresenterAutomationPeer.cs | 14 +++++++++++ .../Peers/DataGridRowAutomationPeer.cs | 20 ++++++++++++++++ src/Avalonia.Controls.DataGrid/DataGrid.cs | 7 ++++++ .../DataGridCell.cs | 7 ++++++ .../DataGridColumnHeader.cs | 7 ++++++ src/Avalonia.Controls.DataGrid/DataGridRow.cs | 6 +++++ .../DataGridColumnHeadersPresenter.cs | 7 ++++++ .../Primitives/DataGridDetailsPresenter.cs | 7 ++++++ 12 files changed, 160 insertions(+) create mode 100644 src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridAutomationPeer.cs create mode 100644 src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridCellAutomationPeer.cs create mode 100644 src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeaderAutomationPeer.cs create mode 100644 src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeadersPresenterAutomationPeer.cs create mode 100644 src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridDetailsPresenterAutomationPeer.cs create mode 100644 src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridRowAutomationPeer.cs diff --git a/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridAutomationPeer.cs b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridAutomationPeer.cs new file mode 100644 index 0000000000..5d181d8567 --- /dev/null +++ b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridAutomationPeer.cs @@ -0,0 +1,18 @@ +using Avalonia.Automation.Peers; + +namespace Avalonia.Controls.Automation.Peers; + +public class DataGridAutomationPeer : ControlAutomationPeer +{ + public DataGridAutomationPeer(DataGrid owner) + : base(owner) + { + } + + public new DataGrid Owner => (DataGrid)base.Owner; + + protected override AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.DataGrid; + } +} diff --git a/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridCellAutomationPeer.cs b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridCellAutomationPeer.cs new file mode 100644 index 0000000000..f1301be70d --- /dev/null +++ b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridCellAutomationPeer.cs @@ -0,0 +1,22 @@ +using Avalonia.Automation.Peers; + +namespace Avalonia.Controls.Automation.Peers; + +public class DataGridCellAutomationPeer : ContentControlAutomationPeer +{ + public DataGridCellAutomationPeer(DataGridCell owner) + : base(owner) + { + } + + public new DataGridCell Owner => (DataGridCell)base.Owner; + + protected override AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.Custom; + } + + protected override bool IsContentElementCore() => true; + + protected override bool IsControlElementCore() => true; +} diff --git a/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeaderAutomationPeer.cs b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeaderAutomationPeer.cs new file mode 100644 index 0000000000..bfcf00607f --- /dev/null +++ b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeaderAutomationPeer.cs @@ -0,0 +1,22 @@ +using Avalonia.Automation.Peers; + +namespace Avalonia.Controls.Automation.Peers; + +public class DataGridColumnHeaderAutomationPeer : ContentControlAutomationPeer +{ + public DataGridColumnHeaderAutomationPeer(DataGridColumnHeader owner) + : base(owner) + { + } + + public new DataGridColumnHeader Owner => (DataGridColumnHeader)base.Owner; + + protected override AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.HeaderItem; + } + + protected override bool IsContentElementCore() => false; + + protected override bool IsControlElementCore() => true; +} diff --git a/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeadersPresenterAutomationPeer.cs b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeadersPresenterAutomationPeer.cs new file mode 100644 index 0000000000..f84951206e --- /dev/null +++ b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridColumnHeadersPresenterAutomationPeer.cs @@ -0,0 +1,23 @@ +using Avalonia.Automation.Peers; +using Avalonia.Controls.Primitives; + +namespace Avalonia.Controls.Automation.Peers; + +public class DataGridColumnHeadersPresenterAutomationPeer : ControlAutomationPeer +{ + public DataGridColumnHeadersPresenterAutomationPeer(DataGridColumnHeadersPresenter owner) + : base(owner) + { + } + + public new DataGridColumnHeadersPresenter Owner => (DataGridColumnHeadersPresenter)base.Owner; + + protected override AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.Header; + } + + protected override bool IsContentElementCore() => false; + + protected override bool IsControlElementCore() => true; +} diff --git a/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridDetailsPresenterAutomationPeer.cs b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridDetailsPresenterAutomationPeer.cs new file mode 100644 index 0000000000..58b79541c5 --- /dev/null +++ b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridDetailsPresenterAutomationPeer.cs @@ -0,0 +1,14 @@ +using Avalonia.Automation.Peers; +using Avalonia.Controls.Primitives; + +namespace Avalonia.Controls.Automation.Peers; + +public class DataGridDetailsPresenterAutomationPeer : ControlAutomationPeer +{ + public DataGridDetailsPresenterAutomationPeer(DataGridDetailsPresenter owner) + : base(owner) + { + } + + public new DataGridDetailsPresenter Owner => (DataGridDetailsPresenter)base.Owner; +} diff --git a/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridRowAutomationPeer.cs b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridRowAutomationPeer.cs new file mode 100644 index 0000000000..4e137a4e74 --- /dev/null +++ b/src/Avalonia.Controls.DataGrid/Automation/Peers/DataGridRowAutomationPeer.cs @@ -0,0 +1,20 @@ +using Avalonia.Controls; + +namespace Avalonia.Automation.Peers +{ + public class DataGridRowAutomationPeer : ControlAutomationPeer + { + public DataGridRowAutomationPeer(DataGridRow owner) + : base(owner) + { + } + + protected override AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.DataItem; + } + + protected override bool IsContentElementCore() => true; + protected override bool IsControlElementCore() => true; + } +} diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index ad7f905c64..c3f428450b 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -22,6 +22,8 @@ using System.Text; using System.Linq; using Avalonia.Input.Platform; using System.ComponentModel.DataAnnotations; +using Avalonia.Automation.Peers; +using Avalonia.Controls.Automation.Peers; using Avalonia.Controls.Utils; using Avalonia.Layout; using Avalonia.Controls.Metadata; @@ -800,6 +802,11 @@ namespace Avalonia.Controls UpdatePseudoClasses(); } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new DataGridAutomationPeer(this); + } + private void SetValueNoCallback(AvaloniaProperty property, T value, BindingPriority priority = BindingPriority.LocalValue) { _areHandlersSuspended = true; diff --git a/src/Avalonia.Controls.DataGrid/DataGridCell.cs b/src/Avalonia.Controls.DataGrid/DataGridCell.cs index 2f5f2c25e0..852b85ff01 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridCell.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridCell.cs @@ -3,6 +3,8 @@ // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. +using Avalonia.Automation.Peers; +using Avalonia.Controls.Automation.Peers; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; @@ -123,6 +125,11 @@ namespace Avalonia.Controls } } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new DataGridCellAutomationPeer(this); + } + /// /// Builds the visual tree for the cell control when a new template is applied. /// diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs index 1eef700a45..579c4d04ad 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs @@ -6,7 +6,9 @@ using System; using System.ComponentModel; using System.Diagnostics; +using Avalonia.Automation.Peers; using Avalonia.Collections; +using Avalonia.Controls.Automation.Peers; using Avalonia.Controls.Metadata; using Avalonia.Controls.Mixins; using Avalonia.Controls.Utils; @@ -87,6 +89,11 @@ namespace Avalonia.Controls PointerExited += DataGridColumnHeader_PointerExited; } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new DataGridColumnHeaderAutomationPeer(this); + } + private void OnAreSeparatorsVisibleChanged(AvaloniaPropertyChangedEventArgs e) { if (!_areHandlersSuspended) diff --git a/src/Avalonia.Controls.DataGrid/DataGridRow.cs b/src/Avalonia.Controls.DataGrid/DataGridRow.cs index 48d6ca7f44..5a312e8b7c 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRow.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRow.cs @@ -15,6 +15,7 @@ using Avalonia.Utilities; using Avalonia.VisualTree; using System; using System.Diagnostics; +using Avalonia.Automation.Peers; using Avalonia.Reactive; namespace Avalonia.Controls @@ -150,6 +151,11 @@ namespace Avalonia.Controls Cells.CellRemoved += DataGridCellCollection_CellRemoved; } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new DataGridRowAutomationPeer(this); + } + private void SetValueNoCallback(AvaloniaProperty property, T value, BindingPriority priority = BindingPriority.LocalValue) { _areHandlersSuspended = true; diff --git a/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs b/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs index fcf72385b2..fb7b256275 100644 --- a/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs +++ b/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs @@ -8,6 +8,8 @@ using Avalonia.Media; using System; using System.Collections.Specialized; using System.Diagnostics; +using Avalonia.Automation.Peers; +using Avalonia.Controls.Automation.Peers; namespace Avalonia.Controls.Primitives { @@ -126,6 +128,11 @@ namespace Avalonia.Controls.Primitives return true; } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new DataGridColumnHeadersPresenterAutomationPeer(this); + } + /// /// Arranges the content of the . /// diff --git a/src/Avalonia.Controls.DataGrid/Primitives/DataGridDetailsPresenter.cs b/src/Avalonia.Controls.DataGrid/Primitives/DataGridDetailsPresenter.cs index 07e7708003..ed7169cae3 100644 --- a/src/Avalonia.Controls.DataGrid/Primitives/DataGridDetailsPresenter.cs +++ b/src/Avalonia.Controls.DataGrid/Primitives/DataGridDetailsPresenter.cs @@ -6,6 +6,8 @@ using System; using System.Collections.Generic; using System.Text; +using Avalonia.Automation.Peers; +using Avalonia.Controls.Automation.Peers; using Avalonia.Media; namespace Avalonia.Controls.Primitives @@ -43,6 +45,11 @@ namespace Avalonia.Controls.Primitives AffectsMeasure(ContentHeightProperty); } + protected override AutomationPeer OnCreateAutomationPeer() + { + return new DataGridDetailsPresenterAutomationPeer(this); + } + /// /// Arranges the content of the . ///