winforms icon indicating copy to clipboard operation
winforms copied to clipboard

ComboBox supports Value UIA pattern, however, does not raise the property change event for value property

Open Tanya-Solyanik opened this issue 2 years ago • 5 comments

According to the required events section in docs.

UIA_ValueValuePropertyId property-changed event. If the control supports the Value control pattern, it must support this event.

UIA_ValueValuePropertyId property-changed event(UIA_AutomationPropertyChangedEventId) should be raised for UIA_ValueValuePropertyId because ComboBox supports the Value control pattern.

The same issue exists in .NET Framework 481. However VS had implemented a workaround - https://github.com/dotnet/project-system/compare/main...adamint:project-system:dev/adamint/legacy-prop-page-accessibility-fixes-august

Customer impact:

VS is hitting this issue in NVDA in property pages on 481. Narrator is handling lack of this property changed event by listening to property changed event for UIA_SelectionItem_ElementSelectedEventId. NVDA does not listed to that event because ComboBox does not support the selection provider and thus NVDA is not updated properly per Roberto Perez investigation.

Tanya-Solyanik avatar Sep 12 '22 23:09 Tanya-Solyanik

I managed to reproduce the issue with NVDA announcements for ComboBox arrow selection in .NET 7, but it looks like the lack of Value changed event is not the root cause. After implementing it I still see that in some cases NVDA doesn't announce changed items:

https://user-images.githubusercontent.com/102954094/190192911-f928bd53-475d-4949-846f-08a93d12cdb5.mp4

The behavior is that when I tab into a ComboBox, NVDA announces value change by arrow keys, but after I do some other actions it may stop announcing. I used Accevent tool to listen to events, and I also observed the same behavior in Accessibility Insights — both show that Value property change event is raised, but it doesn't have any effect on the announcements.

Moreover, if we don't raise the event (our current behavior in .NET 7), NVDA announcements will be exactly the same:

https://user-images.githubusercontent.com/102954094/190197828-ed8b14c0-36ff-4ee1-8278-3230e96f941e.mp4

If NVDA used only the UIA_ValueValuePropertyId changed event, it wouldn't announce change by arrows at all right now, but it still does in some cases, as shown in the second recording. Also, it doesn't reproduce in Narrator.

dmitrii-drobotov avatar Sep 14 '22 15:09 dmitrii-drobotov

Sounds like this part of the fix is not sufficient and we need to fix https://github.com/dotnet/winforms/issues/7764 for completeness. Then we'll wait for the customer request.

Tanya-Solyanik avatar Sep 14 '22 17:09 Tanya-Solyanik

Since this is not a complete fix, we can't service it.

Tanya-Solyanik avatar Sep 14 '22 17:09 Tanya-Solyanik

@rperez030 - .Net 7.0 works better than .NET Framework 481 does, but not after the dropdown was opened and closed (i.e. accessible object for the child list was created). Here are 2 experiments recorded with audio -

ComboBoxAnouncesEditControlContentChanges When I have keyboard focus on the edit field in the combo box, and navigate the content with arrow keys, NVDA announces new selections as expected.

Here is the problematic scenario:

ComboBoxDoesNotAnnounceContentChangeOnKeyboardNavigatioAfterADropDownIsClosed

The important difference is that the dropdown was opened and closed before pressing arrow keys inside the edit box. Not sure why this makes the difference though.

Relevant code:

            this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Items.AddRange(new object[] {
            "Element 1",
            "Element 2",
            "Element 3"});
            this.comboBox1.Location = new System.Drawing.Point(433, 271);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(302, 49);
            this.comboBox1.TabIndex = 2;

Sample Application With DropDownList ComboBox

I still see the value change event processed in the NVDA log with event tracker plug in -

EvtTracker: object: <NVDAObjects.IAccessible.IAccessible object at 0x09756710>
name: None
role: Role.COMBOBOX
event: valueChange
value: Element 1

Full no announcements accEvent and NVDA log

For context, WPF application works as expected with NVDA, here is the accEvent Log - notice the UIA property events accEvent log:

UIA:PropertyEvent	[ValueValue = "Element 2"] Sender: ControlType:UIA_ComboBoxControlTypeId (0xC353), Name:"Select an element", ValueValue:[Not supported]
UIA:AutomationEvent	[Selection_Invalidated] Sender: ControlType:UIA_ComboBoxControlTypeId (0xC353), Name:"Select an element", ValueValue:[Not supported]
UIA:PropertyEvent	[ValueValue = "Element 1"] Sender: ControlType:UIA_ComboBoxControlTypeId (0xC353), Name:"Select an element", ValueValue:[Not supported]
UIA:AutomationEvent	[Selection_Invalidated] Sender: ControlType:UIA_ComboBoxControlTypeId (0xC353), Name:"Select an element", ValueValue:[Not supported]

NVDA event tracker log:

DEBUG - globalPlugins.evtTracker.GlobalPlugin.evtDebugLogging (15:29:27.865) - MainThread (7736):
EvtTracker: object: <NVDAObjects.UIA.ComboBoxWithoutValuePattern object at 0x11608770>
name: Select an element
role: Role.COMBOBOX
event: valueChange
value: Element 2
app module: <'appModuleHandler' (appName 'comboboxexample', process ID 14916) at address ecb8630>
window class name: HwndWrapper[ComboboxExample;;af19d075-2ec0-4903-a13d-0ae1f5885470]
UIA Automation Id: 
class name: ComboBox
IO - speech.speech.speak (15:29:27.865) - MainThread (7736):
Speaking ['Element 2']

Working sample - WpfNotEditableComboBox

Tanya-Solyanik avatar Oct 02 '22 19:10 Tanya-Solyanik

Hi @Tanya-Solyanik ! Thanks for the audio and all the logs. That was very helpful. Based on the log, I believe the first time you tabbed to the Combobox NVDA resorted to use the IAccessible object, not the UIA object. It worked because the valueChange event is fired as expected through MSAA.

Would you mind repeating your second experiment without involving the mouse? Use Alt +Down arrow to expand the Combobox, and escape to collapse. I want to make sure the mouse click didn't introduce a difference in that case.

rperez030 avatar Oct 03 '22 19:10 rperez030

@dmitrii-drobotov - could you please experiment as Roberto requested?

Tanya-Solyanik avatar Oct 19 '22 22:10 Tanya-Solyanik

@rperez030 I repeated the experiment using only keyboard shortcuts, the issue is still present:

https://user-images.githubusercontent.com/102954094/197261785-96ae23bd-fca2-4ec2-8298-985a51746351.mp4

However, I noticed that there was no announcement of ComboBox collapse and it seems like the ComboBox didn't regain focus by NVDA after being collapsed. Instead, it looked like the focus was still on the dropdown list. I wonder if it could be related to focus issues instead of value changed events?

Here is the full NVDA log with event tracker of the first recording: No announcement NVDA log

If I just expand the ComboBox and collapse it without selecting anything, the selection by arrows is announced as expected:

https://user-images.githubusercontent.com/102954094/197262415-fe2a1fff-38cb-4561-ae1b-3c0df061edf0.mp4

Here is the full NVDA log with event tracker of the second recording: Working announcements NVDA log

dmitrii-drobotov avatar Oct 21 '22 18:10 dmitrii-drobotov

Hi @dmitrii-drobotov ! Thanks a lot for including the audio and making it so clear. @Tanya-Solyanik I repeated the experiment with .net 7, and this is my understanding of the situation.

Scenario 1: Tab to the comboBox and navigate using the arrow keys without expanding: It works, but the reason why it works is because NVDA is recognizing the control as an iAccessible object, not an UIA object "NVDAObjects.IAccessible.IAccessible object". It works at this point because the screen reader is listening to valueChange events which are communicate via IAccessible ( NVDA log for scenario 1.txt ). all is well here.

scenario 2: We tab to the combobox, expand with Alt +Down arrow key, select an element and try to navigate after the ComboBox collapses again: When we expand the Combobox, focus switches to the list which is recognized as an UIA object (NVDAObjects.UIA.UIA object) and starts listening to UIA events. When the combobox collapses again, focus goes back, but NVDA keeps paying attention to a list of items which does not exist anymore. In fact, pressing Caps Lock +Tab, the NVDA keystroke to read the element with focus, reports the following: "Element 2 list item off screen". I believe what happens here is that the screen reader expects the list item to fire a loseFocus event, but that event never occurs, so, like @dmitrii-drobotov said, it is a focus issue. NVDA log for scenario 2

rperez030 avatar Oct 24 '22 16:10 rperez030

I believe what happens here is that the screen reader expects the list item to fire a loseFocus event, but that event never occurs,

This is a great lead! We had hit several issues where our objects were held by the accessibility tools and even accessed after controls(HWNDs) were destroyed and our AccessibleObject was disposed. Do you mean AutomationFocusChangedEvent when you say "loseFocus"?

Tanya-Solyanik avatar Nov 11 '22 00:11 Tanya-Solyanik

loseFocus is the specific internal NVDA event that is generated when the screen reader believes that an object no longer has focus.

An UIA focus changed event contains information about the object that originates the event and the ID of the one receiving focus. If a focus change does not occur when the combobox closes, that may explain the issue we are observing here.

rperez030 avatar Nov 11 '22 21:11 rperez030

Created issue #8218 to address the focus issue.

dmitrii-drobotov avatar Nov 17 '22 16:11 dmitrii-drobotov

I believe we fixed the main issue with combobox, closing

Tanya-Solyanik avatar Jul 18 '23 00:07 Tanya-Solyanik