Wpf 当使用HierarchycalDataTemplates和多种项目类型时,如何设置TreeView项目的可访问文本?
我有一个带有TreeView控件的应用程序,它是使用一组表示层次结构中不同级别的数据类型和一组附带的HierarchylDataTemplates构建的。我现在要做的是在树项目上设置适当的AutomationProperties.Name值 通常,我会使用TreeView.ItemContainerStyle来绑定可访问的名称,但这是相当有限的,因为它要求我使用适用于所有类型的绑定路径 然而,在本例中,我更希望能够独立地控制每种类型的可访问名称。例如,在某些层中包含Id可能很有用,但在其他层中不包含Id 我可能会接受使用显示的文本,但尽管我可以轻松地使用TreeView.ItemContainerStyle中的相对资源绑定来获取TreeViewItem,但最终到达模板项中的TextBlock.text值所需的路径却让我无法理解 我也尝试过使用HierarchycalDataTemplate.ItemContainerStyle,但这只适用于子项。更进一步地说,当我试图在每个模板上定义它时,只正确地设置了BazItems,尽管我希望BarItems也能工作 我举了一个简单的例子来说明这个问题。项目类型如下:Wpf 当使用HierarchycalDataTemplates和多种项目类型时,如何设置TreeView项目的可访问文本?,wpf,accessibility,Wpf,Accessibility,我有一个带有TreeView控件的应用程序,它是使用一组表示层次结构中不同级别的数据类型和一组附带的HierarchylDataTemplates构建的。我现在要做的是在树项目上设置适当的AutomationProperties.Name值 通常,我会使用TreeView.ItemContainerStyle来绑定可访问的名称,但这是相当有限的,因为它要求我使用适用于所有类型的绑定路径 然而,在本例中,我更希望能够独立地控制每种类型的可访问名称。例如,在某些层中包含Id可能很有用,但在其他层中不
public sealed class BazItem
{
public BazItem(int id, string name)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name));
}
public int Id { get; }
public string Name { get; }
}
public sealed class BarItem
{
public BarItem(int id, string display)
{
Id = id;
Display = display ?? throw new ArgumentNullException(nameof(display));
Bazs = new ObservableCollection<BazItem>();
}
public int Id { get; }
public string Display { get; }
public ObservableCollection<BazItem> Bazs { get; }
}
public sealed class FooItem
{
public FooItem(int id, string name)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name));
Bars = new ObservableCollection<BarItem>();
}
public int Id { get; }
public string Name { get; }
public ObservableCollection<BarItem> Bars { get; }
}
<HierarchicalDataTemplate DataType="{x:Type local:BazItem}">
<TextBlock Text="{Binding Name, StringFormat='baz: {0}'}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:BarItem}"
ItemsSource="{Binding Bazs}">
<TextBlock Text="{Binding Display, StringFormat='bar: {0}'}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:FooItem}"
ItemsSource="{Binding Bars}">
<TextBlock Text="{Binding Name, StringFormat='foo: {0}'}"/>
</HierarchicalDataTemplate>
<TreeView ItemsSource="{Binding Foos}"/>
相应的模板如下所示:
public sealed class BazItem
{
public BazItem(int id, string name)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name));
}
public int Id { get; }
public string Name { get; }
}
public sealed class BarItem
{
public BarItem(int id, string display)
{
Id = id;
Display = display ?? throw new ArgumentNullException(nameof(display));
Bazs = new ObservableCollection<BazItem>();
}
public int Id { get; }
public string Display { get; }
public ObservableCollection<BazItem> Bazs { get; }
}
public sealed class FooItem
{
public FooItem(int id, string name)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name));
Bars = new ObservableCollection<BarItem>();
}
public int Id { get; }
public string Name { get; }
public ObservableCollection<BarItem> Bars { get; }
}
<HierarchicalDataTemplate DataType="{x:Type local:BazItem}">
<TextBlock Text="{Binding Name, StringFormat='baz: {0}'}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:BarItem}"
ItemsSource="{Binding Bazs}">
<TextBlock Text="{Binding Display, StringFormat='bar: {0}'}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:FooItem}"
ItemsSource="{Binding Bars}">
<TextBlock Text="{Binding Name, StringFormat='foo: {0}'}"/>
</HierarchicalDataTemplate>
<TreeView ItemsSource="{Binding Foos}"/>
最后,视图中的树视图如下所示:
public sealed class BazItem
{
public BazItem(int id, string name)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name));
}
public int Id { get; }
public string Name { get; }
}
public sealed class BarItem
{
public BarItem(int id, string display)
{
Id = id;
Display = display ?? throw new ArgumentNullException(nameof(display));
Bazs = new ObservableCollection<BazItem>();
}
public int Id { get; }
public string Display { get; }
public ObservableCollection<BazItem> Bazs { get; }
}
public sealed class FooItem
{
public FooItem(int id, string name)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name));
Bars = new ObservableCollection<BarItem>();
}
public int Id { get; }
public string Name { get; }
public ObservableCollection<BarItem> Bars { get; }
}
<HierarchicalDataTemplate DataType="{x:Type local:BazItem}">
<TextBlock Text="{Binding Name, StringFormat='baz: {0}'}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:BarItem}"
ItemsSource="{Binding Bazs}">
<TextBlock Text="{Binding Display, StringFormat='bar: {0}'}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:FooItem}"
ItemsSource="{Binding Bars}">
<TextBlock Text="{Binding Name, StringFormat='foo: {0}'}"/>
</HierarchicalDataTemplate>
<TreeView ItemsSource="{Binding Foos}"/>
其中,Foos是基础视图上的ObservableCollection属性。我现在提出的解决方案是更改TreeView.ItemContainerStyle,对树项对象使用值转换器,而不是对象上的属性: TreeView元素:
<TreeView ItemsSource="{Binding ElementName=View, Path=Foos}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="AutomationProperties.Name" Value="{Binding Converter={StaticResource AccessibleConverter}}"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
这是可行的,但由于以下几个原因,它并不理想:
它复制了格式字符串,尽管我可以将它们拉到共享资源位置
值转换器必须首先将对象转换为适当的类型,然后才能生成适当的字符串格式
添加一个新的树项目类型需要我同时触摸模板和值转换器
我也遇到了同样的问题,我解决这个问题的方法是重写绑定TreeViewItem的对象类的ToString方法 例如,在您的情况下,绑定到TreeViewItem的项的类型是BazItem类型,请转到BazItem类并执行以下操作:
public override string ToString()
{
// This is what the Windows Narrator will use now
return "Name of Baz Item";
}