Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
xj-ms opened this issue Nov 27, 2024 · 0 comments

Comments

@xj-ms
Copy link

xj-ms commented Nov 27, 2024

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

<StackPanel>
    <CheckBox x:Name="CheckBox" Content="Show button" />
    <ItemsControl Focusable="False">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type sys:String}">
                <Button Content="{Binding}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>

        <ItemsControl.ItemContainerStyle>
            <Style TargetType="{x:Type ContentPresenter}">
                <Setter Property="Visibility" Value="Collapsed" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsChecked, ElementName=CheckBox}" Value="True">
                        <Setter Property="Visibility" Value="Visible" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ItemsControl.ItemContainerStyle>

        <sys:String>Click Me</sys:String>
    </ItemsControl>
</StackPanel>

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

  3. In the subsequent automation tree update, the same ItemAutomationPeer is obtained from the cache, 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. It remains having no children

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant