-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Added automation peer class for carousel and item #3507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
0ccbedc
36235df
2b9bd47
84d9e00
d0c6b6f
7e14dc2
870b743
a706ca6
c9825f1
662e501
411e39d
b959fbf
631f6b2
ba3c81f
f42f236
41491ee
951774d
8cc836f
7c8c126
c544bb0
3b2d965
4dbba32
ddea9ce
79ea866
32b015d
df21fca
7547a4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using Windows.UI.Xaml.Automation.Peers; | ||
| using Windows.UI.Xaml.Automation.Provider; | ||
| using Windows.UI.Xaml.Controls; | ||
|
|
||
| namespace Microsoft.Toolkit.Uwp.UI.Controls | ||
michael-hawker marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| /// <summary> | ||
| /// Defines a framework element automation peer for the <see cref="Carousel"/> control. | ||
| /// </summary> | ||
| public class CarouselAutomationPeer : ItemsControlAutomationPeer, ISelectionProvider | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="CarouselAutomationPeer"/> class. | ||
| /// </summary> | ||
| /// <param name="owner"> | ||
| /// The <see cref="Carousel" /> that is associated with this <see cref="T:Windows.UI.Xaml.Automation.Peers.CarouselAutomationPeer" />. | ||
| /// </param> | ||
| public CarouselAutomationPeer(Carousel owner) | ||
| : base(owner) | ||
| { | ||
| } | ||
|
|
||
| /// <summary>Gets a value indicating whether the Microsoft UI Automation provider allows more than one child element to be selected concurrently.</summary> | ||
| /// <returns>True if multiple selection is allowed; otherwise, false.</returns> | ||
| public bool CanSelectMultiple => false; | ||
|
|
||
| /// <summary>Gets a value indicating whether the UI Automation provider requires at least one child element to be selected.</summary> | ||
| /// <returns>True if selection is required; otherwise, false.</returns> | ||
| public bool IsSelectionRequired => false; | ||
|
||
|
|
||
| private Carousel OwningCarousel | ||
| { | ||
| get | ||
| { | ||
| return Owner as Carousel; | ||
| } | ||
| } | ||
|
|
||
| /// <summary>Retrieves a UI Automation provider for each child element that is selected.</summary> | ||
| /// <returns>An array of UI Automation providers.</returns> | ||
| public IRawElementProviderSimple[] GetSelection() | ||
| { | ||
| CarouselItem selectedCarouselItem = OwningCarousel.GetCarouselItems().FirstOrDefault(x => x.IsSelected); | ||
michael-hawker marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return selectedCarouselItem != null | ||
| ? new[] { this.ProviderFromPeer(FromElement(selectedCarouselItem)) } | ||
| : new IRawElementProviderSimple[] { }; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the control type for the element that is associated with the UI Automation peer. | ||
| /// </summary> | ||
| /// <returns>The control type.</returns> | ||
| protected override AutomationControlType GetAutomationControlTypeCore() | ||
| { | ||
| return AutomationControlType.List; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType, | ||
| /// differentiates the control represented by this AutomationPeer. | ||
| /// </summary> | ||
| /// <returns>The string that contains the name.</returns> | ||
| protected override string GetClassNameCore() | ||
| { | ||
| return Owner.GetType().Name; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Called by GetName. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// Returns the first of these that is not null or empty: | ||
| /// - Value returned by the base implementation | ||
| /// - Name of the owning Carousel | ||
| /// - Carousel class name | ||
| /// </returns> | ||
| protected override string GetNameCore() | ||
| { | ||
| string name = base.GetNameCore(); | ||
| if (!string.IsNullOrEmpty(name)) | ||
| { | ||
| return name; | ||
| } | ||
|
|
||
| if (this.OwningCarousel != null) | ||
| { | ||
| name = this.OwningCarousel.Name; | ||
| } | ||
|
|
||
| if (string.IsNullOrEmpty(name)) | ||
| { | ||
| name = this.GetClassName(); | ||
|
||
| } | ||
|
|
||
| return name; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the control pattern that is associated with the specified Windows.UI.Xaml.Automation.Peers.PatternInterface. | ||
| /// </summary> | ||
| /// <param name="patternInterface">A value from the Windows.UI.Xaml.Automation.Peers.PatternInterface enumeration.</param> | ||
| /// <returns>The object that supports the specified pattern, or null if unsupported.</returns> | ||
| protected override object GetPatternCore(PatternInterface patternInterface) | ||
| { | ||
| switch (patternInterface) | ||
| { | ||
| case PatternInterface.Selection: | ||
| return this; | ||
| } | ||
|
|
||
| return base.GetPatternCore(patternInterface); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the collection of elements that are represented in the UI Automation tree as immediate | ||
| /// child elements of the automation peer. | ||
| /// </summary> | ||
| /// <returns>The children elements.</returns> | ||
| protected override IList<AutomationPeer> GetChildrenCore() | ||
| { | ||
| Carousel owner = OwningCarousel; | ||
|
|
||
| ItemCollection items = owner.Items; | ||
| if (items.Count <= 0) | ||
| { | ||
| return null; | ||
| } | ||
|
|
||
| List<AutomationPeer> peers = new List<AutomationPeer>(items.Count); | ||
| for (int i = 0; i < items.Count; i++) | ||
| { | ||
| if (owner.ContainerFromIndex(i) is CarouselItem element) | ||
| { | ||
| peers.Add(FromElement(element) ?? CreatePeerForElement(element)); | ||
| } | ||
| } | ||
|
|
||
| return peers; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System.Linq; | ||
| using Windows.UI.Xaml.Automation.Peers; | ||
| using Windows.UI.Xaml.Automation.Provider; | ||
|
|
||
| namespace Microsoft.Toolkit.Uwp.UI.Controls | ||
michael-hawker marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| /// <summary> | ||
| /// Defines a framework element automation peer for the <see cref="CarouselItem"/>. | ||
| /// </summary> | ||
| public class CarouselItemAutomationPeer : FrameworkElementAutomationPeer, ISelectionItemProvider | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="CarouselItemAutomationPeer"/> class. | ||
| /// </summary> | ||
| /// <param name="owner"> | ||
| /// The <see cref="CarouselItem" /> that is associated with this <see cref="T:Windows.UI.Xaml.Automation.Peers.CarouselItemAutomationPeer" />. | ||
| /// </param> | ||
| public CarouselItemAutomationPeer(CarouselItem owner) | ||
| : base(owner) | ||
| { | ||
| } | ||
|
|
||
| /// <summary>Gets a value indicating whether an item is selected.</summary> | ||
| /// <returns>True if the element is selected; otherwise, false.</returns> | ||
| public bool IsSelected => this.OwnerCarouselItem.IsSelected; | ||
|
|
||
| /// <summary>Gets the UI Automation provider that implements ISelectionProvider and acts as the container for the calling object.</summary> | ||
| /// <returns>The UI Automation provider.</returns> | ||
| public IRawElementProviderSimple SelectionContainer | ||
| { | ||
| get | ||
| { | ||
| Carousel parent = this.OwnerCarouselItem.ParentCarousel; | ||
| if (parent == null) | ||
| { | ||
| return null; | ||
| } | ||
|
|
||
| AutomationPeer peer = FromElement(parent); | ||
| return peer != null ? this.ProviderFromPeer(peer) : null; | ||
| } | ||
| } | ||
|
|
||
| private CarouselItem OwnerCarouselItem | ||
| { | ||
| get { return this.Owner as CarouselItem; } | ||
| } | ||
|
|
||
| /// <summary>Adds the current element to the collection of selected items.</summary> | ||
| public void AddToSelection() | ||
| { | ||
| CarouselItem owner = this.OwnerCarouselItem; | ||
| Carousel parent = owner.ParentCarousel; | ||
| parent.SetSelectedItem(owner); | ||
| } | ||
|
|
||
| /// <summary>Removes the current element from the collection of selected items.</summary> | ||
| public void RemoveFromSelection() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So UIA users can reach a state that isn't reachable through mouse interaction? Or is there a way to unselect an item as user?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. The
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is sorted now, removed the code for this. |
||
| { | ||
| CarouselItem owner = this.OwnerCarouselItem; | ||
| Carousel parent = owner.ParentCarousel; | ||
| parent.SelectedItem = null; | ||
| } | ||
|
|
||
| /// <summary>Clears any existing selection and then selects the current element.</summary> | ||
| public void Select() | ||
| { | ||
| CarouselItem owner = this.OwnerCarouselItem; | ||
| Carousel parent = owner.ParentCarousel; | ||
| parent.SetSelectedItem(owner); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the control type for the element that is associated with the UI Automation peer. | ||
| /// </summary> | ||
| /// <returns>The control type.</returns> | ||
| protected override AutomationControlType GetAutomationControlTypeCore() | ||
| { | ||
| return AutomationControlType.ListItem; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType, | ||
| /// differentiates the control represented by this AutomationPeer. | ||
| /// </summary> | ||
| /// <returns>The string that contains the name.</returns> | ||
| protected override string GetClassNameCore() | ||
| { | ||
| return Owner.GetType().Name; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Called by GetName. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// Returns the first of these that is not null or empty: | ||
| /// - Value returned by the base implementation | ||
| /// - Name of the owning CarouselItem | ||
| /// - Carousel class name | ||
| /// </returns> | ||
| protected override string GetNameCore() | ||
| { | ||
| int? index = this.OwnerCarouselItem.ParentCarousel.GetCarouselItems().ToList().IndexOf(this.OwnerCarouselItem); | ||
michael-hawker marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| string name = base.GetNameCore(); | ||
| if (!string.IsNullOrEmpty(name)) | ||
| { | ||
| return $"{name} {index}"; | ||
| } | ||
|
|
||
| if (this.OwnerCarouselItem != null && !string.IsNullOrEmpty(this.OwnerCarouselItem.Name)) | ||
| { | ||
| return this.OwnerCarouselItem.Name; | ||
| } | ||
|
|
||
| if (string.IsNullOrEmpty(name)) | ||
| { | ||
| name = this.GetClassName(); | ||
|
||
| } | ||
|
|
||
| return $"{name} {index}"; | ||
|
||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the control pattern that is associated with the specified Windows.UI.Xaml.Automation.Peers.PatternInterface. | ||
| /// </summary> | ||
| /// <param name="patternInterface">A value from the Windows.UI.Xaml.Automation.Peers.PatternInterface enumeration.</param> | ||
| /// <returns>The object that supports the specified pattern, or null if unsupported.</returns> | ||
| protected override object GetPatternCore(PatternInterface patternInterface) | ||
| { | ||
| switch (patternInterface) | ||
| { | ||
| case PatternInterface.SelectionItem: | ||
| return this; | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not an if case?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be changed. Wanted to keep this in line with the other automation peers which were created for the DataGrid in the toolkit so as not to cause any confusion in code styling.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would argue that an if case would be better in either case since a few interfaces all result in the same behavior. Having a switch case with 4 cases that all do the same (return |
||
|
|
||
| return base.GetPatternCore(patternInterface); | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.