|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Windows.Win32.UI.Accessibility;
namespace System.Windows.Forms;
public partial class PropertyGrid
{
/// <summary>
/// Represents the PropertyGrid accessibility object.
/// Is used only in Accessibility Improvements of level3 to show correct accessible hierarchy.
/// </summary>
internal class PropertyGridAccessibleObject : ControlAccessibleObject
{
/// <summary>
/// Initializes new instance of PropertyGridAccessibleObject
/// </summary>
/// <param name="owningPropertyGrid">The PropertyGrid owning control.</param>
public PropertyGridAccessibleObject(PropertyGrid owningPropertyGrid) : base(owningPropertyGrid) { }
internal override IRawElementProviderFragment.Interface? ElementProviderFromPoint(double x, double y)
{
if (!this.IsOwnerHandleCreated(out PropertyGrid? owningPropertyGrid))
{
return null;
}
Point clientPoint = owningPropertyGrid.PointToClient(new Point((int)x, (int)y));
Control? element = owningPropertyGrid.GetElementFromPoint(clientPoint);
if (element is not null)
{
return element.AccessibilityObject;
}
return base.ElementProviderFromPoint(x, y);
}
internal override IRawElementProviderFragment.Interface? FragmentNavigate(NavigateDirection direction)
{
switch (direction)
{
case NavigateDirection.NavigateDirection_FirstChild:
return GetChildFragment(0);
case NavigateDirection.NavigateDirection_LastChild:
int childFragmentCount = GetChildFragmentCount();
if (childFragmentCount > 0)
{
return GetChildFragment(childFragmentCount - 1);
}
break;
}
return base.FragmentNavigate(direction);
}
/// <summary>
/// Request to return the element in the specified direction regarding the provided child element.
/// </summary>
/// <param name="childFragment">The child element regarding which the target element is searched.</param>
/// <param name="direction">Indicates the direction in which to navigate.</param>
/// <returns>Returns the element in the specified direction.</returns>
internal IRawElementProviderFragment.Interface? ChildFragmentNavigate(AccessibleObject childFragment, NavigateDirection direction)
{
switch (direction)
{
case NavigateDirection.NavigateDirection_Parent:
return this;
case NavigateDirection.NavigateDirection_NextSibling:
int fragmentCount = GetChildFragmentCount();
int childFragmentIndex = GetChildFragmentIndex(childFragment);
int nextChildFragmentIndex = childFragmentIndex + 1;
if (fragmentCount > nextChildFragmentIndex)
{
return GetChildFragment(nextChildFragmentIndex);
}
return null;
case NavigateDirection.NavigateDirection_PreviousSibling:
childFragmentIndex = GetChildFragmentIndex(childFragment);
if (childFragmentIndex > 0)
{
return GetChildFragment(childFragmentIndex - 1);
}
return null;
}
return null;
}
internal override IRawElementProviderFragmentRoot.Interface FragmentRoot => this;
/// <summary>
/// Gets the accessible child corresponding to the specified index.
/// </summary>
/// <param name="index">The child index.</param>
/// <returns>The accessible child.</returns>
internal AccessibleObject? GetChildFragment(int index)
{
if (!this.TryGetOwnerAs(out PropertyGrid? owningPropertyGrid) || index < 0)
{
return null;
}
if (owningPropertyGrid.ToolbarVisible)
{
if (index == 0)
{
return owningPropertyGrid.ToolbarAccessibleObject;
}
index--;
}
if (owningPropertyGrid.GridViewVisible)
{
if (index == 0)
{
return owningPropertyGrid.GridViewAccessibleObject;
}
index--;
}
if (owningPropertyGrid.CommandsVisible)
{
if (index == 0)
{
return owningPropertyGrid.CommandsPaneAccessibleObject;
}
index--;
}
if (owningPropertyGrid.HelpVisible)
{
if (index == 0)
{
return owningPropertyGrid.HelpPaneAccessibleObject;
}
}
return null;
}
/// <summary>
/// Gets the number of children belonging to an accessible object.
/// </summary>
/// <returns>The number of children.</returns>
internal int GetChildFragmentCount()
{
int childCount = 0;
if (!this.TryGetOwnerAs(out PropertyGrid? owningPropertyGrid))
{
return childCount;
}
if (owningPropertyGrid.ToolbarVisible)
{
childCount++;
}
if (owningPropertyGrid.GridViewVisible)
{
childCount++;
}
if (owningPropertyGrid.CommandsVisible)
{
childCount++;
}
if (owningPropertyGrid.HelpVisible)
{
childCount++;
}
return childCount;
}
/// <summary>
/// Return the element in this fragment which has the keyboard focus,
/// </summary>
/// <returns>Return the element in this fragment which has the keyboard focus,
/// if any; otherwise return null.</returns>
internal override IRawElementProviderFragment.Interface? GetFocus() => GetFocused();
/// <summary>
/// Gets the child control index.
/// </summary>
/// <param name="controlAccessibleObject">The control accessible object which index should be found.</param>
/// <returns>The child accessible index or -1 if not found.</returns>
internal int GetChildFragmentIndex(AccessibleObject controlAccessibleObject)
{
int childFragmentCount = GetChildFragmentCount();
for (int i = 0; i < childFragmentCount; i++)
{
AccessibleObject? childFragment = GetChildFragment(i);
if (childFragment == controlAccessibleObject)
{
return i;
}
}
return -1;
}
}
}
|