dotnet / dotnet/wpf

ItemAutomationPeer doesn't properly update Children when the container is initially invisible

Open
#10,127 1 comment 0 reactions 0 assignees View on GitHub
Investigate
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

For an `ItemsControl`, `ItemAutomationPeer` is supposed to help link the items' actual automation peers to the automation tree.
However, in certain situation, `ItemAutomationPeer` doesn't correctly update its `Children`, resulting in automation peers missing from the tree

### Reproduction Steps

Can be reproduced with the following XAML
```XML









<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=CheckBox}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>

Click Me

```

This is just a simplified example. In reality, we have many different types of data items, each with its own data template.

### Expected behavior

After checking the check box and the button becomes visible, a button automation peer should be available in the automation tree for UI automation tools e.g. Windows Narrator should be able to read the button out when focused on it

### Actual behavior

No button automation peers in the automation tree. Windows Narrator isn't able to discover the button

### Regression?

_No response_

### Known Workarounds

_No response_

### Impact

_No response_

### Configuration

_No response_

### Other information

The issue happens when the following conditions are met:
1. The item containers (`ContentPresenter`) are initially invisible, and later become visible
2. The data items are not `UIElement`
3. The data items' equality remains the same before and after the visibility is changed

The automation tree is updated after the layout update. When the visibility is changed, the automation tree is invalidated and the automation tree update goes from the top to the bottom. The problem is that `ItemAutomationPeer.Children` is null while `_ancestorsInvalid` is false and `_childrenValid` is true, which prevents it from updating its children when the automation tree is updated.

1. When an `ItemAutomationPeer` first attempts to update its children, [`GetWrapperPeer`](https://github.com/dotnet/wpf/blob/6e7df620b641b1ad71f95d6645e3d699c21b7e4c/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemAutomationPeer.cs#L201) creates a `FrameworkElementAutomationPeer` for the `ContentPresenter`. However, the wrapper peer won't be able to find any child because the `ContentPresenter` is invisible and doesn't have any visual child. `_ancestorsInvalid` is false and `_childrenValid` is set to true after the automation tree update.

2. When the `ContentPresenter` become visible, the automation peers call `InvalidateAncestorsRecursive` during the layout update, but `_ancestorsInvalid` remains false for the `ItemAutomationPeer` because no other automation peers can reach it through the ancestry link. Things will be different if the data item is an `UIElement`, in which case the `UIElement`'s automation peer will be [obtained as a wrapper peer and the ancestry link is established via `EventSource`](https://github.com/dotnet/wpf/blob/6e7df620b641b1ad71f95d6645e3d699c21b7e4c/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemsControlAutomationPeer.cs#L193-L196).

3. In the subsequent automation tree update, the same `ItemAutomationPeer` is [obtained from the cache](https://github.com/dotnet/wpf/blob/6e7df620b641b1ad71f95d6645e3d699c21b7e4c/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemsControlAutomationPeer.cs#L182), which won't be possible if the data item's equality has changed. Since `_ancestorsInvalid` is false and `_childrenValid` is still true for the `ItemAutomationPeer`, [no more children update will happen](https://github.com/dotnet/wpf/blob/6e7df620b641b1ad71f95d6645e3d699c21b7e4c/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Automation/Peers/AutomationPeer.cs#L1496). It remains having no children

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.