| File: System\Windows\Forms\Controls\TreeView\TreeNode.TreeNodeAccessibleObject.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.Drawing; using Windows.Win32.System.Variant; using Windows.Win32.UI.Accessibility; namespace System.Windows.Forms; public partial class TreeNode { internal sealed class TreeNodeAccessibleObject : AccessibleObject { private readonly TreeNode _owningTreeNode; private readonly TreeView _owningTreeView; public TreeNodeAccessibleObject(TreeNode owningTreeNode, TreeView owningTreeView) { _owningTreeNode = owningTreeNode.OrThrowIfNull(); _owningTreeView = owningTreeView.OrThrowIfNull(); } public override Rectangle Bounds { get { if (!_owningTreeView.IsHandleCreated || !_owningTreeNode.IsVisible) { return Rectangle.Empty; } return _owningTreeNode.RectangleToScreen(_owningTreeNode.Bounds); } } public override string DefaultAction { get { if (_owningTreeView.CheckBoxes) { return _owningTreeNode.Checked ? SR.AccessibleActionUncheck : SR.AccessibleActionCheck; } ExpandCollapseState expandCollapseState = ExpandCollapseState; if (expandCollapseState == ExpandCollapseState.ExpandCollapseState_LeafNode) { return string.Empty; } return expandCollapseState == ExpandCollapseState.ExpandCollapseState_Expanded ? SR.AccessibleActionCollapse : SR.AccessibleActionExpand; } } internal override bool CanGetDefaultActionInternal => false; public override void DoDefaultAction() { if (_owningTreeView.CheckBoxes) { Toggle(); } if (_owningTreeNode.IsExpanded) { Collapse(); } else { Expand(); } return; } internal override IRawElementProviderFragmentRoot.Interface FragmentRoot => _owningTreeView.AccessibilityObject; internal override IRawElementProviderFragment.Interface? FragmentNavigate(NavigateDirection direction) => direction switch { NavigateDirection.NavigateDirection_Parent => Parent ?? _owningTreeView.AccessibilityObject, NavigateDirection.NavigateDirection_FirstChild => _owningTreeNode.IsEditing ? _owningTreeView._labelEdit?.AccessibilityObject : _owningTreeNode.IsExpanded ? _owningTreeNode.FirstNode?.AccessibilityObject : null, NavigateDirection.NavigateDirection_LastChild => _owningTreeNode.IsExpanded ? _owningTreeNode.LastNode?.AccessibilityObject : null, NavigateDirection.NavigateDirection_NextSibling => _owningTreeNode.NextNode?.AccessibilityObject, NavigateDirection.NavigateDirection_PreviousSibling => _owningTreeNode.PrevNode?.AccessibilityObject, _ => base.FragmentNavigate(direction), }; internal override void SelectItem() { _owningTreeView.SelectedNode = _owningTreeNode; } internal override VARIANT GetPropertyValue(UIA_PROPERTY_ID propertyID) => propertyID switch { UIA_PROPERTY_ID.UIA_ControlTypePropertyId => (VARIANT)(int)UIA_CONTROLTYPE_ID.UIA_TreeItemControlTypeId, UIA_PROPERTY_ID.UIA_HasKeyboardFocusPropertyId => (VARIANT)State.HasFlag(AccessibleStates.Focused), UIA_PROPERTY_ID.UIA_IsEnabledPropertyId => (VARIANT)_owningTreeView.Enabled, UIA_PROPERTY_ID.UIA_IsKeyboardFocusablePropertyId => (VARIANT)State.HasFlag(AccessibleStates.Focusable), UIA_PROPERTY_ID.UIA_LevelPropertyId => (VARIANT)(_owningTreeNode.Level + 1), _ => base.GetPropertyValue(propertyID) }; public override AccessibleObject? HitTest(int x, int y) => _owningTreeView.AccessibilityObject.HitTest(x, y); internal int Index => _owningTreeView.Nodes.IndexOf(_owningTreeNode); internal override bool IsPatternSupported(UIA_PATTERN_ID patternId) => patternId switch { UIA_PATTERN_ID.UIA_ExpandCollapsePatternId => true, UIA_PATTERN_ID.UIA_LegacyIAccessiblePatternId => true, UIA_PATTERN_ID.UIA_ScrollItemPatternId => true, UIA_PATTERN_ID.UIA_SelectionItemPatternId => true, UIA_PATTERN_ID.UIA_TogglePatternId when _owningTreeView.CheckBoxes => true, UIA_PATTERN_ID.UIA_ValuePatternId when _owningTreeView.LabelEdit => true, _ => base.IsPatternSupported(patternId), }; public override string? Name => _owningTreeNode.Text; internal override bool CanGetNameInternal => false; public override AccessibleObject? Parent => _owningTreeNode.Parent?.AccessibilityObject; private protected override bool IsInternal => true; public override AccessibleRole Role => _owningTreeView.CheckBoxes ? AccessibleRole.CheckButton : AccessibleRole.OutlineItem; internal override int[] RuntimeId => [ RuntimeIDFirstItem, (int)_owningTreeView.InternalHandle, _owningTreeNode.GetHashCode() ]; public override AccessibleStates State { get { AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; if (!_owningTreeNode.IsVisible) { state |= AccessibleStates.Invisible | AccessibleStates.Offscreen; } if (ExpandCollapseState == ExpandCollapseState.ExpandCollapseState_Expanded) { state |= AccessibleStates.Expanded; } else if (ExpandCollapseState == ExpandCollapseState.ExpandCollapseState_Collapsed) { state |= AccessibleStates.Collapsed; } if (_owningTreeNode.IsSelected) { state |= AccessibleStates.Focused | AccessibleStates.Selected; } if (!_owningTreeView.Enabled) { state |= AccessibleStates.Unavailable; } return state; } } #region Expand-Collapse Pattern internal override void Expand() { if (_owningTreeNode.Nodes.Count == 0) { return; } _owningTreeNode.Expand(); } internal override void Collapse() { if (_owningTreeNode.Nodes.Count == 0) { return; } _owningTreeNode.Collapse(); } internal override ExpandCollapseState ExpandCollapseState { get { if (_owningTreeNode.Nodes.Count == 0) { return ExpandCollapseState.ExpandCollapseState_LeafNode; } return _owningTreeNode.IsExpanded ? ExpandCollapseState.ExpandCollapseState_Expanded : ExpandCollapseState.ExpandCollapseState_Collapsed; } } #endregion #region Scroll Item Pattern internal override void ScrollIntoView() { if (!_owningTreeView.IsHandleCreated || !_owningTreeView.Enabled) { return; } // We don't need to scroll if the item is visible. if (_owningTreeNode.IsVisible) { return; } _owningTreeView.TopNode = _owningTreeNode; } #endregion #region Selection Item Pattern internal override bool IsItemSelected => _owningTreeNode.IsSelected; internal override IRawElementProviderSimple.Interface? ItemSelectionContainer => _owningTreeView.AccessibilityObject; #endregion #region Toggle Pattern internal override void Toggle() => _owningTreeNode.Checked = !_owningTreeNode.Checked; internal override ToggleState ToggleState => _owningTreeNode.Checked ? ToggleState.ToggleState_On : ToggleState.ToggleState_Off; #endregion #region Value Pattern public override string? Value => _owningTreeNode.Text; internal override bool CanGetValueInternal => false; #endregion } }