-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Issue 6530 automation peer for context menu support groups #7335
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
base: main
Are you sure you want to change the base?
Changes from all commits
ed3ed9b
de839a2
0f3b4d6
7732315
8a03304
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 |
---|---|---|
|
@@ -8,13 +8,18 @@ | |
namespace System.Windows.Automation.Peers | ||
{ | ||
/// | ||
public class MenuItemAutomationPeer : FrameworkElementAutomationPeer, IExpandCollapseProvider, IInvokeProvider, IToggleProvider | ||
public class MenuItemAutomationPeer : ItemsControlAutomationPeer, IExpandCollapseProvider, IInvokeProvider, IToggleProvider | ||
{ | ||
/// | ||
public MenuItemAutomationPeer(MenuItem owner): base(owner) | ||
{ | ||
} | ||
|
||
override protected ItemAutomationPeer CreateItemAutomationPeer(object item) | ||
{ | ||
return new MenuItemDataAutomationPeer(item, this); | ||
} | ||
|
||
/// | ||
override protected string GetClassNameCore() | ||
{ | ||
|
@@ -160,16 +165,14 @@ override protected string GetAccessKeyCore() | |
/// | ||
protected override List<AutomationPeer> GetChildrenCore() | ||
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. The existing implementation is not happy with 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 am especially concerned about the grouping vs non-grouping cases in |
||
{ | ||
List<AutomationPeer> children = base.GetChildrenCore(); | ||
|
||
if (ExpandCollapseState.Expanded == ((IExpandCollapseProvider)this).ExpandCollapseState) | ||
{ | ||
ItemsControl owner = (ItemsControl)Owner; | ||
ItemCollection items = owner.Items; | ||
|
||
if (items.Count > 0) | ||
{ | ||
children = new List<AutomationPeer>(items.Count); | ||
List<AutomationPeer> children = new List<AutomationPeer>(items.Count); | ||
for (int i = 0; i < items.Count; i++) | ||
{ | ||
UIElement uiElement = owner.ItemContainerGenerator.ContainerFromIndex(i) as UIElement; | ||
|
@@ -182,12 +185,58 @@ protected override List<AutomationPeer> GetChildrenCore() | |
children.Add(peer); | ||
} | ||
} | ||
|
||
return children; | ||
} | ||
} | ||
|
||
return GetChildrenFromVisualTree(); | ||
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 changes the current behavior, correct? Before the PR, the children contained the visual tree and children. After the PR, it contains visual tree or children. 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. If that is a desired change, it should be explained and mentioned in the risks. 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 tried to create the same behavior like all other controls that support grouping. I have to compare to automation of similar itemcontrols behavior again. I'm a bit out of topic since my last changes. |
||
} | ||
|
||
private List<AutomationPeer> GetChildrenFromVisualTree() | ||
{ | ||
List<AutomationPeer> children = null; | ||
|
||
Iterate(Owner, ref children); | ||
return children; | ||
} | ||
|
||
private static void AddPeerToList(AutomationPeer peer, ref List<AutomationPeer> children) | ||
{ | ||
if (children == null) | ||
children = new List<AutomationPeer>(); | ||
|
||
children.Add(peer); | ||
} | ||
|
||
private static void Iterate(DependencyObject parent, ref List<AutomationPeer> children) | ||
{ | ||
if (parent != null) | ||
{ | ||
AutomationPeer peer = null; | ||
int count = VisualTreeHelper.GetChildrenCount(parent); | ||
for (int i = 0; i < count; i++) | ||
{ | ||
DependencyObject child = VisualTreeHelper.GetChild(parent, i); | ||
|
||
if (child is UIElement uiElement | ||
&& (peer = CreatePeerForElement(uiElement)) != null) | ||
{ | ||
AddPeerToList(peer, ref children); | ||
} | ||
else if (child is UIElement3D uiElemenet3D | ||
&& (peer = UIElement3DAutomationPeer.CreatePeerForElement(uiElemenet3D)) != null) | ||
{ | ||
AddPeerToList(peer, ref children); | ||
} | ||
else | ||
{ | ||
Iterate(child, ref children); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// | ||
void IExpandCollapseProvider.Expand() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
// 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; | ||
using System.Windows.Automation.Provider; | ||
|
||
|
||
namespace System.Windows.Automation.Peers | ||
{ | ||
public class MenuItemDataAutomationPeer : ItemAutomationPeer, IExpandCollapseProvider, IInvokeProvider, IToggleProvider | ||
{ | ||
#region Constructors | ||
|
||
public MenuItemDataAutomationPeer(object item, ItemsControlAutomationPeer itemsControlPeer) | ||
: base(item, itemsControlPeer) | ||
{ | ||
} | ||
|
||
#endregion | ||
|
||
#region AutomationPeer overrides | ||
|
||
protected override string GetClassNameCore() | ||
{ | ||
AutomationPeer wrapperPeer = GetWrapperPeer(); | ||
if (wrapperPeer != null) | ||
{ | ||
return wrapperPeer.GetClassName(); | ||
} | ||
|
||
return "MenuItem"; | ||
} | ||
|
||
protected override AutomationControlType GetAutomationControlTypeCore() | ||
{ | ||
AutomationPeer wrapperPeer = GetWrapperPeer(); | ||
if (wrapperPeer != null) | ||
{ | ||
return wrapperPeer.GetAutomationControlType(); | ||
} | ||
|
||
return AutomationControlType.MenuItem; | ||
} | ||
|
||
public override object GetPattern(PatternInterface patternInterface) | ||
{ | ||
switch (patternInterface) | ||
{ | ||
case PatternInterface.ExpandCollapse: | ||
case PatternInterface.Invoke: | ||
case PatternInterface.Toggle: | ||
return this; | ||
} | ||
|
||
return base.GetPattern(patternInterface); | ||
} | ||
|
||
private void EnsureEnabled() | ||
{ | ||
|
||
FrameworkElementAutomationPeer itemsControllerPeer = GetItemsControlAutomationPeer(); | ||
if (!itemsControllerPeer.IsEnabled()) | ||
{ | ||
throw new ElementNotEnabledException(); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region IExpandCollapseProvider Members | ||
|
||
void IExpandCollapseProvider.Expand() | ||
{ | ||
MenuItemAutomationPeer wrapperPeer = GetWrapperPeer() as MenuItemAutomationPeer; | ||
if (wrapperPeer != null) | ||
{ | ||
((IExpandCollapseProvider)wrapperPeer).Expand(); | ||
} | ||
ThrowElementNotAvailableException(); | ||
} | ||
|
||
void IExpandCollapseProvider.Collapse() | ||
{ | ||
MenuItemAutomationPeer wrapperPeer = GetWrapperPeer() as MenuItemAutomationPeer; | ||
if (wrapperPeer != null) | ||
{ | ||
((IExpandCollapseProvider)wrapperPeer).Collapse(); | ||
} | ||
ThrowElementNotAvailableException(); | ||
} | ||
|
||
ExpandCollapseState IExpandCollapseProvider.ExpandCollapseState | ||
{ | ||
get | ||
{ | ||
MenuItemAutomationPeer wrapperPeer = GetWrapperPeer() as MenuItemAutomationPeer; | ||
if (wrapperPeer != null) | ||
{ | ||
return ((IExpandCollapseProvider)wrapperPeer).ExpandCollapseState; | ||
} | ||
ThrowElementNotAvailableException(); | ||
return ExpandCollapseState.LeafNode; | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region IInvokeProvider Members | ||
|
||
void IInvokeProvider.Invoke() | ||
{ | ||
// check if enabled | ||
EnsureEnabled(); | ||
|
||
MenuItemAutomationPeer wrapperPeer = GetWrapperPeer() as MenuItemAutomationPeer; | ||
if (wrapperPeer != null) | ||
{ | ||
((IInvokeProvider)wrapperPeer).Invoke(); | ||
} | ||
else | ||
{ | ||
ThrowElementNotAvailableException(); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region IToggleProvider Members | ||
|
||
void IToggleProvider.Toggle() | ||
{ | ||
MenuItemAutomationPeer wrapperPeer = GetWrapperPeer() as MenuItemAutomationPeer; | ||
if (wrapperPeer != null) | ||
{ | ||
((IToggleProvider)wrapperPeer).Toggle(); | ||
} | ||
else | ||
{ | ||
ThrowElementNotAvailableException(); | ||
} | ||
} | ||
|
||
ToggleState IToggleProvider.ToggleState | ||
{ | ||
get | ||
{ | ||
MenuItemAutomationPeer wrapperPeer = GetWrapperPeer() as MenuItemAutomationPeer; | ||
if (wrapperPeer != null) | ||
{ | ||
return ((IToggleProvider)wrapperPeer).ToggleState; | ||
} | ||
ThrowElementNotAvailableException(); | ||
return ToggleState.Indeterminate; | ||
} | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.