Skip to content

Commit 0ccbedc

Browse files
committed
Added automation peer class for carousel and item
1 parent 49a88c7 commit 0ccbedc

File tree

4 files changed

+329
-0
lines changed

4 files changed

+329
-0
lines changed

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Windows.Foundation;
1111
using Windows.UI.Xaml;
1212
using Windows.UI.Xaml.Automation;
13+
using Windows.UI.Xaml.Automation.Peers;
1314
using Windows.UI.Xaml.Controls;
1415
using Windows.UI.Xaml.Input;
1516
using Windows.UI.Xaml.Media;
@@ -522,6 +523,17 @@ protected override void PrepareContainerForItemOverride(DependencyObject element
522523
{
523524
carouselItem.IsSelected = true;
524525
}
526+
527+
carouselItem.ParentCarousel = this;
528+
}
529+
530+
/// <summary>
531+
/// Creates AutomationPeer (<see cref="UIElement.OnCreateAutomationPeer"/>)
532+
/// </summary>
533+
/// <returns>An automation peer for this <see cref="Carousel"/>.</returns>
534+
protected override AutomationPeer OnCreateAutomationPeer()
535+
{
536+
return new CarouselAutomationPeer(this);
525537
}
526538

527539
private void OnCarouselItemSelected(object sender, EventArgs e)
@@ -530,5 +542,19 @@ private void OnCarouselItemSelected(object sender, EventArgs e)
530542

531543
SelectedItem = ItemFromContainer(item);
532544
}
545+
546+
internal IEnumerable<CarouselItem> GetCarouselItems()
547+
{
548+
return Enumerable
549+
.Range(0, Items.Count)
550+
.Select(idx => (CarouselItem)ContainerFromIndex(idx))
551+
.Where(i => i != null);
552+
}
553+
554+
internal void SetSelectedItem(CarouselItem owner)
555+
{
556+
var item = ItemFromContainer(owner);
557+
SelectedItem = item;
558+
}
533559
}
534560
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
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 System.Linq;
7+
using Windows.UI.Xaml.Automation.Peers;
8+
using Windows.UI.Xaml.Automation.Provider;
9+
using Windows.UI.Xaml.Controls;
10+
11+
namespace Microsoft.Toolkit.Uwp.UI.Controls
12+
{
13+
/// <summary>
14+
/// Defines a framework element automation peer for the <see cref="Carousel"/> control.
15+
/// </summary>
16+
public class CarouselAutomationPeer : ItemsControlAutomationPeer, ISelectionProvider
17+
{
18+
/// <summary>
19+
/// Initializes a new instance of the <see cref="CarouselAutomationPeer"/> class.
20+
/// </summary>
21+
/// <param name="owner">
22+
/// The <see cref="Carousel" /> that is associated with this <see cref="T:Windows.UI.Xaml.Automation.Peers.CarouselAutomationPeer" />.
23+
/// </param>
24+
public CarouselAutomationPeer(Carousel owner)
25+
: base(owner)
26+
{
27+
}
28+
29+
/// <summary>Gets a value indicating whether the Microsoft UI Automation provider allows more than one child element to be selected concurrently.</summary>
30+
/// <returns>True if multiple selection is allowed; otherwise, false.</returns>
31+
public bool CanSelectMultiple => false;
32+
33+
/// <summary>Gets a value indicating whether the UI Automation provider requires at least one child element to be selected.</summary>
34+
/// <returns>True if selection is required; otherwise, false.</returns>
35+
public bool IsSelectionRequired => false;
36+
37+
private Carousel OwningCarousel
38+
{
39+
get
40+
{
41+
return Owner as Carousel;
42+
}
43+
}
44+
45+
/// <summary>Retrieves a UI Automation provider for each child element that is selected.</summary>
46+
/// <returns>An array of UI Automation providers.</returns>
47+
public IRawElementProviderSimple[] GetSelection()
48+
{
49+
CarouselItem selectedCarouselItem = OwningCarousel.GetCarouselItems().FirstOrDefault(x => x.IsSelected);
50+
return selectedCarouselItem != null
51+
? new[] { this.ProviderFromPeer(FromElement(selectedCarouselItem)) }
52+
: new IRawElementProviderSimple[] { };
53+
}
54+
55+
/// <summary>
56+
/// Gets the control type for the element that is associated with the UI Automation peer.
57+
/// </summary>
58+
/// <returns>The control type.</returns>
59+
protected override AutomationControlType GetAutomationControlTypeCore()
60+
{
61+
return AutomationControlType.List;
62+
}
63+
64+
/// <summary>
65+
/// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType,
66+
/// differentiates the control represented by this AutomationPeer.
67+
/// </summary>
68+
/// <returns>The string that contains the name.</returns>
69+
protected override string GetClassNameCore()
70+
{
71+
return Owner.GetType().Name;
72+
}
73+
74+
/// <summary>
75+
/// Called by GetName.
76+
/// </summary>
77+
/// <returns>
78+
/// Returns the first of these that is not null or empty:
79+
/// - Value returned by the base implementation
80+
/// - Name of the owning Carousel
81+
/// - Carousel class name
82+
/// </returns>
83+
protected override string GetNameCore()
84+
{
85+
string name = base.GetNameCore();
86+
if (!string.IsNullOrEmpty(name))
87+
{
88+
return name;
89+
}
90+
91+
if (this.OwningCarousel != null)
92+
{
93+
name = this.OwningCarousel.Name;
94+
}
95+
96+
if (string.IsNullOrEmpty(name))
97+
{
98+
name = this.GetClassName();
99+
}
100+
101+
return name;
102+
}
103+
104+
/// <summary>
105+
/// Gets the control pattern that is associated with the specified Windows.UI.Xaml.Automation.Peers.PatternInterface.
106+
/// </summary>
107+
/// <param name="patternInterface">A value from the Windows.UI.Xaml.Automation.Peers.PatternInterface enumeration.</param>
108+
/// <returns>The object that supports the specified pattern, or null if unsupported.</returns>
109+
protected override object GetPatternCore(PatternInterface patternInterface)
110+
{
111+
switch (patternInterface)
112+
{
113+
case PatternInterface.Selection:
114+
return this;
115+
}
116+
117+
return base.GetPatternCore(patternInterface);
118+
}
119+
120+
/// <summary>
121+
/// Gets the collection of elements that are represented in the UI Automation tree as immediate
122+
/// child elements of the automation peer.
123+
/// </summary>
124+
/// <returns>The children elements.</returns>
125+
protected override IList<AutomationPeer> GetChildrenCore()
126+
{
127+
Carousel owner = OwningCarousel;
128+
129+
ItemCollection items = owner.Items;
130+
if (items.Count <= 0)
131+
{
132+
return null;
133+
}
134+
135+
List<AutomationPeer> peers = new List<AutomationPeer>(items.Count);
136+
for (int i = 0; i < items.Count; i++)
137+
{
138+
if (owner.ContainerFromIndex(i) is CarouselItem element)
139+
{
140+
peers.Add(FromElement(element) ?? CreatePeerForElement(element));
141+
}
142+
}
143+
144+
return peers;
145+
}
146+
}
147+
}

Microsoft.Toolkit.Uwp.UI.Controls/Carousel/CarouselItem.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using Windows.UI.Xaml;
7+
using Windows.UI.Xaml.Automation.Peers;
78
using Windows.UI.Xaml.Controls;
89
using Windows.UI.Xaml.Controls.Primitives;
910
using Windows.UI.Xaml.Input;
@@ -33,6 +34,8 @@ public CarouselItem()
3334
RegisterPropertyChangedCallback(SelectorItem.IsSelectedProperty, OnIsSelectedChanged);
3435
}
3536

37+
internal Carousel ParentCarousel { get; set; }
38+
3639
/// <inheritdoc/>
3740
protected override void OnPointerEntered(PointerRoutedEventArgs e)
3841
{
@@ -57,6 +60,15 @@ protected override void OnPointerPressed(PointerRoutedEventArgs e)
5760
VisualStateManager.GoToState(this, IsSelected ? PressedSelectedState : PressedState, true);
5861
}
5962

63+
/// <summary>
64+
/// Creates AutomationPeer (<see cref="UIElement.OnCreateAutomationPeer"/>)
65+
/// </summary>
66+
/// <returns>An automation peer for this <see cref="CarouselItem"/>.</returns>
67+
protected override AutomationPeer OnCreateAutomationPeer()
68+
{
69+
return new CarouselItemAutomationPeer(this);
70+
}
71+
6072
internal event EventHandler Selected;
6173

6274
private void OnIsSelectedChanged(DependencyObject sender, DependencyProperty dp)
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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 Windows.UI.Xaml.Automation.Peers;
7+
using Windows.UI.Xaml.Automation.Provider;
8+
9+
namespace Microsoft.Toolkit.Uwp.UI.Controls
10+
{
11+
/// <summary>
12+
/// Defines a framework element automation peer for the <see cref="CarouselItem"/>.
13+
/// </summary>
14+
public class CarouselItemAutomationPeer : FrameworkElementAutomationPeer, ISelectionItemProvider
15+
{
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="CarouselItemAutomationPeer"/> class.
18+
/// </summary>
19+
/// <param name="owner">
20+
/// The <see cref="CarouselItem" /> that is associated with this <see cref="T:Windows.UI.Xaml.Automation.Peers.CarouselItemAutomationPeer" />.
21+
/// </param>
22+
public CarouselItemAutomationPeer(CarouselItem owner)
23+
: base(owner)
24+
{
25+
}
26+
27+
/// <summary>Gets a value indicating whether an item is selected.</summary>
28+
/// <returns>True if the element is selected; otherwise, false.</returns>
29+
public bool IsSelected => this.OwnerCarouselItem.IsSelected;
30+
31+
/// <summary>Gets the UI Automation provider that implements ISelectionProvider and acts as the container for the calling object.</summary>
32+
/// <returns>The UI Automation provider.</returns>
33+
public IRawElementProviderSimple SelectionContainer
34+
{
35+
get
36+
{
37+
Carousel parent = this.OwnerCarouselItem.ParentCarousel;
38+
if (parent == null)
39+
{
40+
return null;
41+
}
42+
43+
AutomationPeer peer = FromElement(parent);
44+
return peer != null ? this.ProviderFromPeer(peer) : null;
45+
}
46+
}
47+
48+
private CarouselItem OwnerCarouselItem
49+
{
50+
get { return this.Owner as CarouselItem; }
51+
}
52+
53+
/// <summary>Adds the current element to the collection of selected items.</summary>
54+
public void AddToSelection()
55+
{
56+
CarouselItem owner = this.OwnerCarouselItem;
57+
Carousel parent = owner.ParentCarousel;
58+
parent.SetSelectedItem(owner);
59+
}
60+
61+
/// <summary>Removes the current element from the collection of selected items.</summary>
62+
public void RemoveFromSelection()
63+
{
64+
CarouselItem owner = this.OwnerCarouselItem;
65+
Carousel parent = owner.ParentCarousel;
66+
parent.SelectedItem = null;
67+
}
68+
69+
/// <summary>Clears any existing selection and then selects the current element.</summary>
70+
public void Select()
71+
{
72+
CarouselItem owner = this.OwnerCarouselItem;
73+
Carousel parent = owner.ParentCarousel;
74+
parent.SetSelectedItem(owner);
75+
}
76+
77+
/// <summary>
78+
/// Gets the control type for the element that is associated with the UI Automation peer.
79+
/// </summary>
80+
/// <returns>The control type.</returns>
81+
protected override AutomationControlType GetAutomationControlTypeCore()
82+
{
83+
return AutomationControlType.ListItem;
84+
}
85+
86+
/// <summary>
87+
/// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType,
88+
/// differentiates the control represented by this AutomationPeer.
89+
/// </summary>
90+
/// <returns>The string that contains the name.</returns>
91+
protected override string GetClassNameCore()
92+
{
93+
return Owner.GetType().Name;
94+
}
95+
96+
/// <summary>
97+
/// Called by GetName.
98+
/// </summary>
99+
/// <returns>
100+
/// Returns the first of these that is not null or empty:
101+
/// - Value returned by the base implementation
102+
/// - Name of the owning CarouselItem
103+
/// - Carousel class name
104+
/// </returns>
105+
protected override string GetNameCore()
106+
{
107+
int? index = this.OwnerCarouselItem.ParentCarousel.GetCarouselItems().ToList().IndexOf(this.OwnerCarouselItem);
108+
109+
string name = base.GetNameCore();
110+
if (!string.IsNullOrEmpty(name))
111+
{
112+
return $"{name} {index}";
113+
}
114+
115+
if (this.OwnerCarouselItem != null && !string.IsNullOrEmpty(this.OwnerCarouselItem.Name))
116+
{
117+
return this.OwnerCarouselItem.Name;
118+
}
119+
120+
if (string.IsNullOrEmpty(name))
121+
{
122+
name = this.GetClassName();
123+
}
124+
125+
return $"{name} {index}";
126+
}
127+
128+
/// <summary>
129+
/// Gets the control pattern that is associated with the specified Windows.UI.Xaml.Automation.Peers.PatternInterface.
130+
/// </summary>
131+
/// <param name="patternInterface">A value from the Windows.UI.Xaml.Automation.Peers.PatternInterface enumeration.</param>
132+
/// <returns>The object that supports the specified pattern, or null if unsupported.</returns>
133+
protected override object GetPatternCore(PatternInterface patternInterface)
134+
{
135+
switch (patternInterface)
136+
{
137+
case PatternInterface.SelectionItem:
138+
return this;
139+
}
140+
141+
return base.GetPatternCore(patternInterface);
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)