Skip to content
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

Fix issue with displaying empty ListViewGroups #4789

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 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.Drawing;
using static Interop;

Expand Down Expand Up @@ -108,7 +109,13 @@ internal override int[]? RuntimeId

public override AccessibleObject? GetChild(int index)
{
if (!_owningListView.IsHandleCreated || index < 0 || index >= GetChildCount())
if (!_owningListView.IsHandleCreated || index < 0)
{
return null;
}

IReadOnlyList<ListViewGroup> visibleGroups = GetVisibleGroups();
if (index >= GetChildCount(visibleGroups))
{
return null;
}
Expand All @@ -120,7 +127,7 @@ internal override int[]? RuntimeId

if (!OwnerHasDefaultGroup)
{
return _owningListView.Groups[index].AccessibilityObject;
return visibleGroups[index].AccessibilityObject;
}

// Default group has the last index out of the Groups.Count
Expand All @@ -129,7 +136,7 @@ internal override int[]? RuntimeId
// default group is the first before other groups.
return index == 0
? _owningListView.DefaultGroup.AccessibilityObject
: _owningListView.Groups[index - 1].AccessibilityObject;
: visibleGroups[index - 1].AccessibilityObject;
}

public override int GetChildCount()
Expand All @@ -139,9 +146,14 @@ public override int GetChildCount()
return 0;
}

return GetChildCount(GetVisibleGroups());
}

private int GetChildCount(IReadOnlyList<ListViewGroup> visibleGroups)
{
if (ShowGroupAccessibleObject)
{
return OwnerHasDefaultGroup ? _owningListView.Groups.Count + 1 : _owningListView.Groups.Count;
return OwnerHasDefaultGroup ? visibleGroups.Count + 1 : visibleGroups.Count;
}

return _owningListView.Items.Count;
Expand Down Expand Up @@ -282,6 +294,26 @@ internal override UiaCore.IRawElementProviderSimple[] GetSelection()
return selectedItemProviders;
}

internal IReadOnlyList<ListViewGroup> GetVisibleGroups()
{
List<ListViewGroup> list = new();
if (!ShowGroupAccessibleObject)
{
return list;
}

foreach (ListViewGroup listViewGroup in _owningListView.Groups)
{
if (listViewGroup.AccessibilityObject is ListViewGroup.ListViewGroupAccessibleObject listViewGroupAccessibleObject
&& listViewGroupAccessibleObject.GetVisibleItems().Count > 0)
{
list.Add(listViewGroup);
}
}

return list;
}

public override AccessibleObject? HitTest(int x, int y)
{
if (!_owningListView.IsHandleCreated)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// 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.Drawing;
using static System.Windows.Forms.ListView;
using static Interop;
using static Interop.ComCtl32;

Expand All @@ -13,6 +15,7 @@ public partial class ListViewGroup
internal class ListViewGroupAccessibleObject : AccessibleObject
{
private readonly ListView _owningListView;
private readonly ListViewAccessibleObject _owningListViewAccessibilityObject;
private readonly ListViewGroup _owningGroup;
private readonly bool _owningGroupIsDefault;

Expand All @@ -26,6 +29,9 @@ public ListViewGroupAccessibleObject(ListViewGroup owningGroup, bool owningGroup
? _owningGroup.Items[0].ListView
: throw new InvalidOperationException(nameof(owningGroup.ListView)));

_owningListViewAccessibilityObject = _owningListView.AccessibilityObject as ListView.ListViewAccessibleObject
?? throw new InvalidOperationException(nameof(_owningListView.AccessibilityObject));

_owningGroupIsDefault = owningGroupIsDefault;
}

Expand All @@ -45,8 +51,8 @@ public override Rectangle Bounds
User32.SendMessageW(_owningListView, (User32.WM)ComCtl32.LVM.GETGROUPRECT, (IntPtr)CurrentIndex, ref groupRect);

return new Rectangle(
_owningListView.AccessibilityObject.Bounds.X + groupRect.left,
_owningListView.AccessibilityObject.Bounds.Y + groupRect.top,
_owningListViewAccessibilityObject.Bounds.X + groupRect.left,
_owningListViewAccessibilityObject.Bounds.Y + groupRect.top,
groupRect.right - groupRect.left,
groupRect.bottom - groupRect.top);
}
Expand Down Expand Up @@ -77,7 +83,7 @@ internal override int[]? RuntimeId
{
get
{
var owningListViewRuntimeId = _owningListView.AccessibilityObject.RuntimeId;
var owningListViewRuntimeId = _owningListViewAccessibilityObject.RuntimeId;
if (owningListViewRuntimeId is null)
{
return base.RuntimeId;
Expand Down Expand Up @@ -148,6 +154,20 @@ private bool GetNativeFocus()
_ => base.GetPropertyValue(propertyID)
};

internal IReadOnlyList<ListViewItem> GetVisibleItems()
{
List<ListViewItem> visibleItems = new();
foreach (ListViewItem listViewItem in _owningGroup.Items)
{
if (listViewItem.ListView is not null)
{
visibleItems.Add(listViewItem);
}
}

return visibleItems;
}

internal override UiaCore.IRawElementProviderFragment? FragmentNavigate(UiaCore.NavigateDirection direction)
{
if (!_owningListView.IsHandleCreated || _owningListView.VirtualMode)
Expand All @@ -158,11 +178,11 @@ private bool GetNativeFocus()
switch (direction)
{
case UiaCore.NavigateDirection.Parent:
return _owningListView.AccessibilityObject;
return _owningListViewAccessibilityObject;
case UiaCore.NavigateDirection.NextSibling:
return (_owningListView.AccessibilityObject as ListView.ListViewAccessibleObject)?.GetNextChild(this);
return _owningListViewAccessibilityObject.GetNextChild(this);
case UiaCore.NavigateDirection.PreviousSibling:
return (_owningListView.AccessibilityObject as ListView.ListViewAccessibleObject)?.GetPreviousChild(this);
return _owningListViewAccessibilityObject.GetPreviousChild(this);
case UiaCore.NavigateDirection.FirstChild:
int childCount = GetChildCount();
if (childCount > 0)
Expand Down Expand Up @@ -195,12 +215,13 @@ private bool GetNativeFocus()

if (!_owningGroupIsDefault)
{
if (index < 0 || index >= _owningGroup.Items.Count)
IReadOnlyList<ListViewItem> visibleItems = GetVisibleItems();
if (index < 0 || index >= visibleItems.Count)
{
return null;
}

return _owningGroup.Items[index].AccessibilityObject;
return visibleItems[index].AccessibilityObject;
}

foreach (ListViewItem? item in _owningListView.Items)
Expand Down Expand Up @@ -294,7 +315,7 @@ public override int GetChildCount()
}
else
{
return _owningGroup.Items.Count;
return GetVisibleItems().Count;
}
}

Expand Down
Loading