Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 当使用HierarchycalDataTemplates和多种项目类型时,如何设置TreeView项目的可访问文本?_Wpf_Accessibility - Fatal编程技术网

Wpf 当使用HierarchycalDataTemplates和多种项目类型时,如何设置TreeView项目的可访问文本?

Wpf 当使用HierarchycalDataTemplates和多种项目类型时,如何设置TreeView项目的可访问文本?,wpf,accessibility,Wpf,Accessibility,我有一个带有TreeView控件的应用程序,它是使用一组表示层次结构中不同级别的数据类型和一组附带的HierarchylDataTemplates构建的。我现在要做的是在树项目上设置适当的AutomationProperties.Name值 通常,我会使用TreeView.ItemContainerStyle来绑定可访问的名称,但这是相当有限的,因为它要求我使用适用于所有类型的绑定路径 然而,在本例中,我更希望能够独立地控制每种类型的可访问名称。例如,在某些层中包含Id可能很有用,但在其他层中不

我有一个带有TreeView控件的应用程序,它是使用一组表示层次结构中不同级别的数据类型和一组附带的HierarchylDataTemplates构建的。我现在要做的是在树项目上设置适当的AutomationProperties.Name值

通常,我会使用TreeView.ItemContainerStyle来绑定可访问的名称,但这是相当有限的,因为它要求我使用适用于所有类型的绑定路径

然而,在本例中,我更希望能够独立地控制每种类型的可访问名称。例如,在某些层中包含Id可能很有用,但在其他层中不包含Id

我可能会接受使用显示的文本,但尽管我可以轻松地使用TreeView.ItemContainerStyle中的相对资源绑定来获取TreeViewItem,但最终到达模板项中的TextBlock.text值所需的路径却让我无法理解

我也尝试过使用HierarchycalDataTemplate.ItemContainerStyle,但这只适用于子项。更进一步地说,当我试图在每个模板上定义它时,只正确地设置了BazItems,尽管我希望BarItems也能工作

我举了一个简单的例子来说明这个问题。项目类型如下:

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";
}