| File: System\Windows\Forms\Controls\ToolStrips\ToolStripDropDownItemAccessibleObject.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms\System.Windows.Forms.csproj (System.Windows.Forms) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Windows.Forms.Layout; using Windows.Win32.System.Variant; using Windows.Win32.UI.Accessibility; namespace System.Windows.Forms; public class ToolStripDropDownItemAccessibleObject : ToolStripItem.ToolStripItemAccessibleObject { private readonly ToolStripDropDownItem _owner; public ToolStripDropDownItemAccessibleObject(ToolStripDropDownItem item) : base(item) { _owner = item; } public override AccessibleRole Role { get { AccessibleRole role = Owner.AccessibleRole; if (role != AccessibleRole.Default) { return role; } return AccessibleRole.MenuItem; } } public override void DoDefaultAction() { if (Owner is ToolStripDropDownItem item && item.HasDropDownItems) { item.ShowDropDown(); } else { base.DoDefaultAction(); } } internal override bool IsIAccessibleExSupported() { return true; } internal override bool IsPatternSupported(UIA_PATTERN_ID patternId) { if (patternId == UIA_PATTERN_ID.UIA_ExpandCollapsePatternId && _owner.HasDropDownItems) { return true; } else { return base.IsPatternSupported(patternId); } } internal override VARIANT GetPropertyValue(UIA_PROPERTY_ID propertyID) => propertyID switch { UIA_PROPERTY_ID.UIA_IsOffscreenPropertyId when _owner.Owner is ToolStripDropDown toolStripDropDown => (VARIANT)!toolStripDropDown.Visible, _ => base.GetPropertyValue(propertyID) }; internal override void Expand() => DoDefaultAction(); internal override void Collapse() { if (_owner.DropDown.Visible) { _owner.DropDown.Close(); } } internal override ExpandCollapseState ExpandCollapseState { get { return _owner.DropDown.Visible ? ExpandCollapseState.ExpandCollapseState_Expanded : ExpandCollapseState.ExpandCollapseState_Collapsed; } } public override AccessibleObject? GetChild(int index) { if (!_owner.HasDropDownItems) { return null; } return _owner.DropDown.AccessibilityObject.GetChild(index); } public override int GetChildCount() { if (!_owner.HasDropDownItems) { return -1; } // Do not expose child items when the submenu is collapsed to prevent Narrator from announcing // invisible menu items when Narrator is in item's mode (CAPSLOCK + Arrow Left/Right) or // in scan mode (CAPSLOCK + Space) if (ExpandCollapseState == ExpandCollapseState.ExpandCollapseState_Collapsed) { return 0; } if (_owner.DropDown.LayoutRequired) { LayoutTransaction.DoLayout(_owner.DropDown, _owner.DropDown, PropertyNames.Items); } return _owner.DropDown.AccessibilityObject.GetChildCount(); } internal int GetChildFragmentIndex(ToolStripItem.ToolStripItemAccessibleObject child) { if (_owner.DropDownItems is null) { return -1; } for (int i = 0; i < _owner.DropDownItems.Count; i++) { if (_owner.DropDownItems[i].Available && child.Owner == _owner.DropDownItems[i]) { return i; } } return -1; } /// <summary> /// Gets the number of children belonging to an accessible object. /// </summary> /// <returns>The number of children.</returns> internal int GetChildFragmentCount() { if (_owner.DropDownItems is null) { return -1; } int count = 0; for (int i = 0; i < _owner.DropDownItems.Count; i++) { if (_owner.DropDownItems[i].Available) { count++; } } return count; } internal AccessibleObject? GetChildFragment(int index, NavigateDirection direction) { if (_owner.DropDown.AccessibilityObject is ToolStrip.ToolStripAccessibleObject toolStripAccessibleObject) { return toolStripAccessibleObject.GetChildFragment(index, direction); } return null; } internal override IRawElementProviderFragment.Interface? FragmentNavigate(NavigateDirection direction) { switch (direction) { case NavigateDirection.NavigateDirection_NextSibling: case NavigateDirection.NavigateDirection_PreviousSibling: if (_owner.Owner is not ToolStripDropDown dropDown) { break; } int index = dropDown.DisplayedItems.IndexOf(_owner); if (index == -1) { Debug.Fail("No item matched the index?"); return null; } index += direction == NavigateDirection.NavigateDirection_NextSibling ? 1 : -1; if (index >= 0 && index < dropDown.DisplayedItems.Count) { ToolStripItem item = dropDown.DisplayedItems[index]; if (item is ToolStripControlHost controlHostItem) { return controlHostItem.ControlAccessibilityObject; } return item.AccessibilityObject; } return null; case NavigateDirection.NavigateDirection_FirstChild: case NavigateDirection.NavigateDirection_LastChild: // Don't add invisible items to the accessibility tree, // they might not have been created yet. return _owner.DropDown.Visible ? _owner.DropDown.AccessibilityObject : null; } return base.FragmentNavigate(direction); } }