Question

I have a WPF DataGrid control that is binding to a collection of objects. Everything is rendering on-screen as it should be.

ToString() has been overridden due to requirements elsewhere in the application.

The issue is that, when read by a screen reader (such as Microsoft's built-in Narrator), or when inspected via a tool like AccChecker / Inspect, the control's name is the overridden ToString value.

I want to be able to specify a descriptive name for the screen reader, but I can't find a method of doing so. I've tried setting AutomationProperties.Name, AutomationProperties.ItemType, and so forth, but none of the properties in AutomationProperties seem to have the desired effect.

Optimally, I'd be able to do this for both the data item itself, and also for the individual members of the columns.

Here's a complete demo of the issue I'm experiencing:

<DataGrid x:Name="dgTest" ItemsSource="{Binding}" AutoGenerateColumns="false" AutomationProperties.Name="Test">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Name" IsReadOnly="True" Width="2*" AutomationProperties.Name="Test2">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Name}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="ID" IsReadOnly="True" Width="2*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Id}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

And the code:

public class FooItem
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return string.Concat(Id.ToString(), " : ", Name);
    }
}

public partial class MainWindow : Window
{
    public readonly List<FooItem> fooList = new List<FooItem>();
    public MainWindow()
    {
        fooList.Add(new FooItem { Id = Guid.NewGuid(), Name = "Test 1" });
        fooList.Add(new FooItem { Id = Guid.NewGuid(), Name = "Test 2" });
        fooList.Add(new FooItem { Id = Guid.NewGuid(), Name = "Test 3" });

        InitializeComponent();
        dgTest.DataContext = fooList;
    }
}

And just for completeness, here's a screenshot of Inspector. full size image Inspector screenshot

Was it helpful?

Solution

I found a solution... I had to use a style on DataGrid.ItemContainerStyle and DataGridTemplateColumn.HeaderStyle to set AutomationProperties.Name.

Ex:

<DataGrid x:Name="dgTest" ItemsSource="{Binding}" AutoGenerateColumns="false" AutomationProperties.Name="Test"> 
    <DataGrid.ItemContainerStyle>
         <Style>
              <Setter Property="AutomationProperties.Name" Value="Row Item" />
         </Style>
    </DataGrid.ItemContainerStyle>
    <DataGrid.Columns> 
        <DataGridTemplateColumn Header="Name" IsReadOnly="True" Width="2*" AutomationProperties.Name="Test2"> 
            <DataGridTemplateColumn.CellTemplate> 
                <DataTemplate> 
                    <TextBlock Text="{Binding Path=Name}"/> 
                </DataTemplate> 
            </DataGridTemplateColumn.CellTemplate> 
        </DataGridTemplateColumn> 
            <DataGridTemplateColumn Header="ID" IsReadOnly="True" Width="2*"> 
            <DataGridTemplateColumn.CellTemplate> 
                <DataTemplate> 
                    <TextBlock Text="{Binding Path=Id}"/> 
                </DataTemplate> 
            </DataGridTemplateColumn.CellTemplate> 
        </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top