4

I have a Grouped GridView in my app. I'd like to set AutomationProperties.Name on the GridViewHeaderItem object, which I can do using a <Style> like the following:

<Style x:Key="GridViewHeaderStyle" TargetType="GridViewHeaderItem">
    <Setter Property="AutomationProperties.Name" Value="This Works" />
</Style>

The following does NOT work, regardless of what I bind to:

<Style x:Key="GridViewHeaderStyle" TargetType="GridViewHeaderItem">
    <Setter Property="AutomationProperties.Name" Value="{Binding DataContext.PropertyDoesNotWork}" />
</Style>

How can I set the AutomationProperties.Name at run-time? Is there some event that is fired when the GridViewHeaderItem object is created?

Thank you.

Chris Leyva
  • 3,478
  • 1
  • 26
  • 47

2 Answers2

2

SOLUTION: AutomationPeers

Here is how I was able to set AutomationProperties.Name on the GridViewHeaderItem at runtime, without having to use the VisualTreeHelper. Basically, I used the AutomationPeer classes to grab a reference to the GridViewHeaderItem and then set the AutomationProperties.Name in that way.

Control.xaml

<GridView ...>
    <GridView.GroupStyle>
        <GroupStyle ...>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <!-- Important to handle the Loaded event -->
                    <TextBlock Loaded="TextBlockLoaded" Text="Hi" />
                </DateTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </GridView.GroupStyle>
</GridView>

Control.xaml.cs

private void TextBlockLoaded(object sender, RoutedEventArgs e)
{
    var textBlockAP = FrameworkElementAutomationPeer.CreatePeerForElement(sender as UIElement);
    if (textBlockAP != null) 
    {
        var parentAP = textBlockAP.Navigate(AutomationNavigationDirection.Parent);
        if (parentAP is GridViewHeaderItemAutomationPeer gridViewHeaderItemAP)
        {
            var gridViewHeaderItem = gridViewHeaderItemAP.Owner as GridViewHeaderItem;
            var itemGroup = gridViewHeaderItem.Content as SomeItemGroupClass;
            AutomationProperties.SetName(gridViewHeaderItem, itemGroup.Title ?? string.Empty);
        }
    }
}

This worked wonders for me with my very specific use case.

Chris Leyva
  • 3,478
  • 1
  • 26
  • 47
1

Instead of specifying the name in the Style, define the HeaderTemplate of the GridView.GroupStyle and use data binding there

<Grid AutomationProperties.Name="{Binding MyNameProperty}"> 
   ...
</Grid>
Michael S. Scherotter
  • 10,715
  • 3
  • 34
  • 57
  • This answer would work but what if you wanted the property to be the same throughout your whole application? Sorry I know that is not OPs question but was just curious. – Max Young Apr 22 '18 at 19:28
  • Max, If you create a Style in App.Xaml for GridView without an x:Key, it will be the new default style for all GridViews. set its GroupStyle and it will apply to all GridView instances. – Michael S. Scherotter May 02 '18 at 11:52
  • Unfortunately, this does not work. I messed up when testing this answer and prematurely marked it as the answer and assigned the bounty. Anyway, this does not set the AutomationProperty.Name on the GridViewHeaderItem, which is what Windows' Narrator app uses to read the names of the control when it has focus. I'm playing around with some other ideas now to try to get it to work. Thanks, though. – Chris Leyva May 02 '18 at 16:08
  • @MichaelS.Scherotter It took a long time but I was finally able to post the solution that worked for me. Thanks again for taking a look. – Chris Leyva Jun 21 '18 at 20:42