-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
- .NET Core Version: 4.8
- Windows version: (
winver) 1909 (OS Build 183.63.476( - Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
- Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? No
If you have a ListView that uses a FrameworkElementFactory, each row in the list is represented by a GridViewRowPresenter. That presenter creates a ContentPresenter for each child.
When the content of the cell is another UIElement, however, the automation tree has two elements for each cell (one for the ContentPresenter and one for the contained UIElement). This causes problems with navigation using caps+arrows (you stop at the ContentPresenter before navigating to the UIElement) and with some (cough, Narrator) screen readers that read out the ContentPresenter as "Custom".
There should be a way to have the automation peers of the GridViewRowPresenter skip the ContentPresenters of cells that have a UIElement as their content (for example, provide a way to specify the AutomationPeers of the content created using a FrameworkElementFactory).
See the following source for code that replicates the problem.
public partial class MainWindow : Window
{
private readonly ObservableCollection _source;
public MainWindow()
{
InitializeComponent();
_source = new ObservableCollection<RowViewModel>();
this.View.ItemsSource = _source;
GridView grid = this.View.View as GridView;
grid.Columns.Add(CreateGridViewColumn(100.0, "Alpha", 5.0));
grid.Columns.Add(CreateGridViewColumn(100.0, "Beta", 5.0));
grid.Columns.Add(CreateGridViewColumn(100.0, "Gamma", 5.0));
_source.Add(new RowViewModel(1));
_source.Add(new RowViewModel(2));
_source.Add(new RowViewModel(3));
}
private GridViewColumn CreateGridViewColumn(double width, string name, double padding)
{
GridViewColumn column = new GridViewColumn();
column.Width = width + padding;
column.Header = name;
column.CellTemplate = MainWindow.CreateItemDataTemplate(name);
return column;
}
private static DataTemplate CreateItemDataTemplate(string columnName)
{
var template = new DataTemplate();
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ContentPresenter));
factory.SetBinding(ContentPresenter.ContentProperty, new Binding(string.Format(CultureInfo.InvariantCulture, "[{0}]", columnName)));
template.VisualTree = factory;
return template;
}
}
class RowViewModel
{
private readonly string _id;
private readonly Dictionary<string, object> _rowMap = new Dictionary<string, object>();
public RowViewModel(int id)
{
_id = id.ToString();
}
public object this[string columnName]
{
get
{
if (!_rowMap.TryGetValue(columnName, out object value))
{
value = new TextBlock() { Text = columnName + _id };
}
return value;
}
}
}