Skip to content

Commit 6ebb1c6

Browse files
committed
Added automation peers for BladeView and BladeItem controls
1 parent 2b610c4 commit 6ebb1c6

File tree

5 files changed

+229
-0
lines changed

5 files changed

+229
-0
lines changed

Microsoft.Toolkit.Uwp.UI.Controls/BladeView/BladeItem.Properties.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public bool IsOpen
8484
set { SetValue(IsOpenProperty, value); }
8585
}
8686

87+
internal BladeView ParentBladeView { get; set; }
88+
8789
private static void IsOpenChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
8890
{
8991
BladeItem bladeItem = (BladeItem)dependencyObject;

Microsoft.Toolkit.Uwp.UI.Controls/BladeView/BladeItem.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using Microsoft.Toolkit.Uwp.Extensions;
77
using Windows.UI.Xaml;
88
using Windows.UI.Xaml.Automation;
9+
using Windows.UI.Xaml.Automation.Peers;
910
using Windows.UI.Xaml.Controls;
11+
using Microsoft.Toolkit.Uwp.UI.Automation.Peers;
1012

1113
namespace Microsoft.Toolkit.Uwp.UI.Controls
1214
{
@@ -92,6 +94,15 @@ protected override void OnCollapsed(EventArgs args)
9294
}
9395
}
9496

97+
/// <summary>
98+
/// Creates AutomationPeer (<see cref="UIElement.OnCreateAutomationPeer"/>)
99+
/// </summary>
100+
/// <returns>An automation peer for this <see cref="BladeItem"/>.</returns>
101+
protected override AutomationPeer OnCreateAutomationPeer()
102+
{
103+
return new BladeItemAutomationPeer(this);
104+
}
105+
95106
private void OnSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
96107
{
97108
if (IsExpanded)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Linq;
6+
using Microsoft.Toolkit.Uwp.UI.Controls;
7+
using Windows.UI.Xaml.Automation.Peers;
8+
using Windows.UI.Xaml.Automation.Provider;
9+
10+
namespace Microsoft.Toolkit.Uwp.UI.Automation.Peers
11+
{
12+
/// <summary>
13+
/// Defines a framework element automation peer for the <see cref="BladeItem"/>.
14+
/// </summary>
15+
public class BladeItemAutomationPeer : FrameworkElementAutomationPeer
16+
{
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="BladeItemAutomationPeer"/> class.
19+
/// </summary>
20+
/// <param name="owner">
21+
/// The <see cref="BladeItem" /> that is associated with this <see cref="T:Windows.UI.Xaml.Automation.Peers.BladeItemAutomationPeer" />.
22+
/// </param>
23+
public BladeItemAutomationPeer(BladeItem owner)
24+
: base(owner)
25+
{
26+
}
27+
28+
private BladeItem OwnerBladeItem
29+
{
30+
get { return this.Owner as BladeItem; }
31+
}
32+
33+
/// <summary>
34+
/// Gets the control type for the element that is associated with the UI Automation peer.
35+
/// </summary>
36+
/// <returns>The control type.</returns>
37+
protected override AutomationControlType GetAutomationControlTypeCore()
38+
{
39+
return AutomationControlType.Custom;
40+
}
41+
42+
/// <summary>
43+
/// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType,
44+
/// differentiates the control represented by this AutomationPeer.
45+
/// </summary>
46+
/// <returns>The string that contains the name.</returns>
47+
protected override string GetClassNameCore()
48+
{
49+
return Owner.GetType().Name;
50+
}
51+
52+
/// <summary>
53+
/// Called by GetName.
54+
/// </summary>
55+
/// <returns>
56+
/// Returns the first of these that is not null or empty:
57+
/// - Value returned by the base implementation
58+
/// - Name of the owning BladeItem
59+
/// - Carousel class name
60+
/// </returns>
61+
protected override string GetNameCore()
62+
{
63+
int? index = this.OwnerBladeItem.ParentBladeView.GetBladeItems().ToList().IndexOf(this.OwnerBladeItem);
64+
65+
string name = base.GetNameCore();
66+
if (!string.IsNullOrEmpty(name))
67+
{
68+
return $"{name} {index}";
69+
}
70+
71+
if (this.OwnerBladeItem != null && !string.IsNullOrEmpty(this.OwnerBladeItem.Name))
72+
{
73+
return this.OwnerBladeItem.Name;
74+
}
75+
76+
if (string.IsNullOrEmpty(name))
77+
{
78+
name = this.GetClassName();
79+
}
80+
81+
return $"{name} {index}";
82+
}
83+
}
84+
}

Microsoft.Toolkit.Uwp.UI.Controls/BladeView/BladeView.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
using Windows.Foundation.Collections;
1212
using Windows.UI.Core;
1313
using Windows.UI.Xaml;
14+
using Windows.UI.Xaml.Automation.Peers;
1415
using Windows.UI.Xaml.Controls;
16+
using Microsoft.Toolkit.Uwp.UI.Automation.Peers;
1517

1618
namespace Microsoft.Toolkit.Uwp.UI.Controls
1719
{
@@ -65,6 +67,7 @@ protected override void PrepareContainerForItemOverride(DependencyObject element
6567
if (blade != null)
6668
{
6769
blade.VisibilityChanged += BladeOnVisibilityChanged;
70+
blade.ParentBladeView = this;
6871
}
6972

7073
base.PrepareContainerForItemOverride(element, item);
@@ -83,6 +86,15 @@ protected override void ClearContainerForItemOverride(DependencyObject element,
8386
base.ClearContainerForItemOverride(element, item);
8487
}
8588

89+
/// <summary>
90+
/// Creates AutomationPeer (<see cref="UIElement.OnCreateAutomationPeer"/>)
91+
/// </summary>
92+
/// <returns>An automation peer for this <see cref="BladeView"/>.</returns>
93+
protected override AutomationPeer OnCreateAutomationPeer()
94+
{
95+
return new BladeViewAutomationPeer(this);
96+
}
97+
8698
private void CycleBlades()
8799
{
88100
ActiveBlades = new ObservableCollection<BladeItem>();
@@ -200,5 +212,13 @@ private void ItemsVectorChanged(IObservableVector<object> sender, IVectorChanged
200212
GetScrollViewer()?.ChangeView(_scrollViewer.ScrollableWidth, null, null);
201213
}
202214
}
215+
216+
internal IEnumerable<BladeItem> GetBladeItems()
217+
{
218+
return Enumerable
219+
.Range(0, Items.Count)
220+
.Select(idx => (BladeItem)ContainerFromIndex(idx))
221+
.Where(i => i != null);
222+
}
203223
}
204224
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Collections.Generic;
6+
using Microsoft.Toolkit.Uwp.UI.Controls;
7+
using Windows.UI.Xaml.Automation.Peers;
8+
using Windows.UI.Xaml.Controls;
9+
10+
namespace Microsoft.Toolkit.Uwp.UI.Automation.Peers
11+
{
12+
/// <summary>
13+
/// Defines a framework element automation peer for the <see cref="BladeView"/> control.
14+
/// </summary>
15+
public class BladeViewAutomationPeer : ItemsControlAutomationPeer
16+
{
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="BladeViewAutomationPeer"/> class.
19+
/// </summary>
20+
/// <param name="owner">
21+
/// The <see cref="BladeView" /> that is associated with this <see cref="T:Windows.UI.Xaml.Automation.Peers.BladeViewAutomationPeer" />.
22+
/// </param>
23+
public BladeViewAutomationPeer(BladeView owner)
24+
: base(owner)
25+
{
26+
}
27+
28+
private BladeView OwningBladeView
29+
{
30+
get
31+
{
32+
return Owner as BladeView;
33+
}
34+
}
35+
36+
/// <summary>
37+
/// Gets the control type for the element that is associated with the UI Automation peer.
38+
/// </summary>
39+
/// <returns>The control type.</returns>
40+
protected override AutomationControlType GetAutomationControlTypeCore()
41+
{
42+
return AutomationControlType.Custom;
43+
}
44+
45+
/// <summary>
46+
/// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType,
47+
/// differentiates the control represented by this AutomationPeer.
48+
/// </summary>
49+
/// <returns>The string that contains the name.</returns>
50+
protected override string GetClassNameCore()
51+
{
52+
return Owner.GetType().Name;
53+
}
54+
55+
/// <summary>
56+
/// Called by GetName.
57+
/// </summary>
58+
/// <returns>
59+
/// Returns the first of these that is not null or empty:
60+
/// - Value returned by the base implementation
61+
/// - Name of the owning BladeView
62+
/// - BladeView class name
63+
/// </returns>
64+
protected override string GetNameCore()
65+
{
66+
string name = base.GetNameCore();
67+
if (!string.IsNullOrEmpty(name))
68+
{
69+
return name;
70+
}
71+
72+
if (this.OwningBladeView != null)
73+
{
74+
name = this.OwningBladeView.Name;
75+
}
76+
77+
if (string.IsNullOrEmpty(name))
78+
{
79+
name = this.GetClassName();
80+
}
81+
82+
return name;
83+
}
84+
85+
/// <summary>
86+
/// Gets the collection of elements that are represented in the UI Automation tree as immediate
87+
/// child elements of the automation peer.
88+
/// </summary>
89+
/// <returns>The children elements.</returns>
90+
protected override IList<AutomationPeer> GetChildrenCore()
91+
{
92+
BladeView owner = OwningBladeView;
93+
94+
ItemCollection items = owner.Items;
95+
if (items.Count <= 0)
96+
{
97+
return null;
98+
}
99+
100+
List<AutomationPeer> peers = new List<AutomationPeer>(items.Count);
101+
for (int i = 0; i < items.Count; i++)
102+
{
103+
if (owner.ContainerFromIndex(i) is BladeItem element)
104+
{
105+
peers.Add(FromElement(element) ?? CreatePeerForElement(element));
106+
}
107+
}
108+
109+
return peers;
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)