winforms icon indicating copy to clipboard operation
winforms copied to clipboard

[Accessibility] SubItems displayed incorrectly in Inspect or AccessibilityInsights after a column is removed from the ListView.

Open Amy-Li03 opened this issue 2 years ago • 7 comments

.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+?

  1. This issue doesn't repro on .NET Core 3.1.
  2. The subItems doesn't display in Inspect in .NET 5.0.
  3. 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: Repro

.NET Framework: FX

Steps to reproduce

  1. Extract and open attached app: TestApp.zip
  2. Build and run this app.
  3. Launch Inspect or Accessibility Insight tool.
  4. Focus on the subItems --- these subItems displayed correctly in Inspect.
  5. Click "Remove Column" button.
  6. Refresh Inspect tool.
  7. Focus on the subItems --- these subItems displayed incorrectly in Inspect.

ReproSteps

Amy-Li03 avatar Jul 25 '22 10:07 Amy-Li03

This looks to be related to https://github.com/dotnet/winforms/issues/7481

dmitrii-drobotov avatar Jul 26 '22 09:07 dmitrii-drobotov

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.

Animation5

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:

Animation6

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)?

dmitrii-drobotov avatar Aug 09 '22 18:08 dmitrii-drobotov

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 avatar Aug 09 '22 18:08 merriemcgaw

@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 avatar Aug 10 '22 01:08 Tanya-Solyanik

@Tanya-Solyanik Yes, Inspect, Accessibility Insights and Narrator (both narrator scan on and scan off) tools all can repro this issue.

Amy-Li03 avatar Aug 10 '22 07:08 Amy-Li03

Ok, I see, thanks for the feedback! Maybe I could come up with a different solution then, and definitely later for .NET 8.

dmitrii-drobotov avatar Aug 10 '22 10:08 dmitrii-drobotov

I've looked at this issue and can suggest few options to fix it:

  1. 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 because LVM.SUBITEMHITTEST returns a shifted index. I mean that if you remove the column with the index = 1 and after that call HitTest from the same position you'll receive a response with the same iSubItem value as before despite the SubItem is different, but in WinForms ListViewItem.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.
  2. Add an indicator to SubItem such as Disabled/Deleted which will be set on column removing. If the value is true we will skip these SubItems in AccessibilityObject children. But the restoration of this value will remain on a user.
  3. Add a link to a ColumnHeader in the ListViewSubItem and replace the mechanism of finding child AO from SubItemIndex to ColumnLink.

@Tanya-Solyanik what do you think?

NikitaSemenovAkvelon avatar Sep 20 '22 12:09 NikitaSemenovAkvelon

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. 7492Retest

Ashley-Li avatar Oct 19 '23 08:10 Ashley-Li