From babced709359a2950fc5af6ab43bc44c0b28eefd Mon Sep 17 00:00:00 2001 From: Tanya Solyanik Date: Thu, 22 Feb 2024 10:32:39 -0800 Subject: [PATCH] System.InvalidOperationException: ListView at System.Windows.Forms.ListViewGroup.ListViewGroupAccessibleObject..ctor(ListViewGroup owningGroup, Boolean owningGroupIsDefault) at System.Windows.Forms.ListViewGroup.get_AccessibilityObject() at System.Windows.Forms.ListView.OnGotFocus(EventArgs e) --- .../ListView.ListViewAccessibleObject.cs | 2 +- ...ViewGroup.ListViewGroupAccessibleObject.cs | 11 +++------- .../Forms/Controls/ListView/ListViewGroup.cs | 22 +++++++++++++++++-- ...roup.ListViewGroupAccessibleObjectTests.cs | 8 ++++--- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.ListViewAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.ListViewAccessibleObject.cs index 37d97170bf7..5aee0f19adb 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.ListViewAccessibleObject.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListView.ListViewAccessibleObject.cs @@ -313,7 +313,7 @@ internal IReadOnlyList GetVisibleGroups() IReadOnlyList visibleGroups = GetVisibleGroups(); for (int i = 0; i < visibleGroups.Count; i++) { - if (visibleGroups[i].AccessibilityObject.Bounds.Contains(hitTestPoint)) + if (visibleGroups[i].AccessibilityObject?.Bounds.Contains(hitTestPoint) == true) { return visibleGroups[i].AccessibilityObject; } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.ListViewGroupAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.ListViewGroupAccessibleObject.cs index cbc7113e986..9150036f765 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.ListViewGroupAccessibleObject.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.ListViewGroupAccessibleObject.cs @@ -17,17 +17,12 @@ internal sealed class ListViewGroupAccessibleObject : AccessibleObject private readonly ListViewGroup _owningGroup; private readonly bool _owningGroupIsDefault; - public ListViewGroupAccessibleObject(ListViewGroup owningGroup, bool owningGroupIsDefault) + public ListViewGroupAccessibleObject(ListViewGroup owningGroup, ListView listView, bool owningGroupIsDefault) { _owningGroup = owningGroup.OrThrowIfNull(); + _owningListView = listView.OrThrowIfNull(); - // Using item from group for getting of ListView is a workaround for https://github.com/dotnet/winforms/issues/4019 - _owningListView = owningGroup.ListView - ?? (owningGroup.Items.Count > 0 && _owningGroup.Items[0].ListView is ListView listView - ? listView - : throw new InvalidOperationException(nameof(owningGroup.ListView))); - - _owningListViewAccessibilityObject = _owningListView.AccessibilityObject as ListView.ListViewAccessibleObject + _owningListViewAccessibilityObject = _owningListView.AccessibilityObject as ListViewAccessibleObject ?? throw new InvalidOperationException(nameof(_owningListView.AccessibilityObject)); _owningGroupIsDefault = owningGroupIsDefault; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.cs index 6ba0a0894a1..c2d179eb7b6 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListView/ListViewGroup.cs @@ -74,8 +74,26 @@ public ListViewGroup(string? header, HorizontalAlignment headerAlignment) : this _headerAlignment = headerAlignment; } - internal AccessibleObject AccessibilityObject - => _accessibilityObject ??= new ListViewGroupAccessibleObject(this, ListView?.Groups.Contains(this) == false); + internal AccessibleObject? AccessibilityObject + { + get + { + if (_accessibilityObject is not null) + { + return _accessibilityObject; + } + + // Using item from group for getting of ListView is a workaround for https://github.com/dotnet/winforms/issues/4019 + var listView = ListView; + listView ??= Items.Count > 0 ? Items[0].ListView : null; + if (listView is not null) + { + _accessibilityObject = new ListViewGroupAccessibleObject(this, listView, owningGroupIsDefault: !listView.Groups.Contains(this)); + } + + return _accessibilityObject; + } + } /// /// The text displayed in the group header. diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/AccessibleObjects/ListViewGroup.ListViewGroupAccessibleObjectTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/AccessibleObjects/ListViewGroup.ListViewGroupAccessibleObjectTests.cs index 54cef46e394..262f810c6ad 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/AccessibleObjects/ListViewGroup.ListViewGroupAccessibleObjectTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/AccessibleObjects/ListViewGroup.ListViewGroupAccessibleObjectTests.cs @@ -1326,10 +1326,12 @@ public void ListViewGroupAccessibleObject_IsPatternSupported_ReturnFalse_ForColl }; listView.Groups.Add(listGroup); - ListViewItem item = new("Test"); - item.Group = listGroup; + ListViewItem item = new("Test") + { + Group = listGroup + }; listView.Items.Add(item); - ListViewGroupAccessibleObject accessibleObject = new(listGroup, false); + ListViewGroupAccessibleObject accessibleObject = new(listGroup, listView, false); if (createHandle) {