winforms
winforms copied to clipboard
[Accessibility] SubItems displayed incorrectly in Inspect or AccessibilityInsights after a column is removed from the ListView.
.NET version
.NET SDK 7.0.100-preview.7.22370.3
Did it work in .NET Framework?
Yes
Did it work in any of the earlier releases of .NET Core or .NET 5+?
- This issue doesn't repro on .NET Core 3.1.
- The subItems doesn't display in Inspect in .NET 5.0.
- This issue all can reproduced on .NET 6.0 & 7.0.
Issue description
The SubItems displayed incorrectly in Inspect and Accessibility Insight tool after remove a column of ListView.
.NET Core:
.NET Framework:
Steps to reproduce
- Extract and open attached app: TestApp.zip
- Build and run this app.
- Launch Inspect or Accessibility Insight tool.
- Focus on the subItems --- these subItems displayed correctly in Inspect.
- Click "Remove Column" button.
- Refresh Inspect tool.
- Focus on the subItems --- these subItems displayed incorrectly in Inspect.
This looks to be related to https://github.com/dotnet/winforms/issues/7481
The bug exists because when a column is removed, the corresponding subitems are not deleted and still stored in the same order. A way to fix it is to recreate the handle of ListView after column removal. After that the visible content will be the same as in Inspect/Narrator but it does affect the behavior.
Right now column removal behavior looks logical but there would be a problem if something triggers recreation of ListView's handle. There are multiple operations that do it, for example, I've made a button that executes listView1.Scrollable = !listView1.Scrollable;
which internally calls RecreateHandle()
and as a result it indirectly changes the subitems.
In .NET Framework it's also the same.
If we add a call to RecreateHandle()
after column removal, it will fix above problem and also the Inspect/Narrator issue:
I think it's more correct but I'm not sure if it's worth changing the behavior.
@merriemcgaw @Tanya-Solyanik what do you think, should we go with this solution (2nd gif)?
At this point I don't think it's the right time to change behavior, though I do think that may be the right approach. Let's put this on the back burner and consider for .NET 8.
@merriemcgaw - I wouldn't recreate handle even in NET8 because is a breaking change that could manifest itself very subtly. @Amy-Li03 - does this repro for any other accessibility tools? Narrator in scan mode?
@Tanya-Solyanik Yes, Inspect, Accessibility Insights and Narrator (both narrator scan on and scan off) tools all can repro this issue.
Ok, I see, thanks for the feedback! Maybe I could come up with a different solution then, and definitely later for .NET 8.
I've looked at this issue and can suggest few options to fix it:
- Delete the
SubItem
on removing a column. In this way, we can save the consistency between columns and sub items. Moreover, it looks like a native control works in the same way becauseLVM.SUBITEMHITTEST
returns a shifted index. I mean that if you remove the column with the index = 1 and after that callHitTest
from the same position you'll receive a response with the sameiSubItem
value as before despite theSubItem
is different, but in WinFormsListViewItem.SubItems[1]
will be skipped but still contained in the collection. Nevertheless, it may be a breaking change, probably. If someone realized their own application with an opportunity to remove and restore columns. - Add an indicator to
SubItem
such asDisabled
/Deleted
which will be set on column removing. If the value is true we will skip theseSubItems
inAccessibilityObject
children. But the restoration of this value will remain on a user. - Add a link to a
ColumnHeader
in theListViewSubItem
and replace the mechanism of finding childAO
fromSubItemIndex
toColumnLink
.
@Tanya-Solyanik what do you think?
Verified this issue from main branch of winforms repo, this issue have been fixed. Now the SubItems displayed correctly in Inspect tool after remove a column of ListView.