屏幕阅读器 WPF 群组样式

37
我正在尝试为GroupStyle控件模板中的控件设置AutomationProperties.Name属性,但似乎没有任何效果。我已经在模板中的Expander上设置了它,即使我只插入一些文本而没有绑定,它也没有显示出来。我还尝试在GroupItem上放置一个setter,但那也没用。我有点不知所措了。我希望在组项上设置该属性可以解决这个问题。
XAML:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="WpfApplication8.MainWindow"
        x:Name="win"
        Title="MainWindow"
        Width="640"
        Height="480">

  <Grid x:Name="LayoutRoot">
    <ListBox x:Name="lstbx"
             Margin="71,45,99,78"
             ItemsSource="{Binding ElementName=win,
                                       Path=Samples}">
      <ListBox.GroupStyle>
        <GroupStyle>
          <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
              <Setter Property="AutomationProperties.Name"
                      Value="this is a test" />
              <Setter Property="KeyboardNavigation.TabNavigation"
                      Value="Cycle" />
              <Setter Property="Template">
                <Setter.Value>
                  <ControlTemplate TargetType="{x:Type GroupItem}">
                    <Expander Name="templateLstBxExpander"
                              AutomationProperties.Name="test test test"
                              IsExpanded="True">

                      <Expander.Header>
                        <StackPanel Orientation="Horizontal">
                          <Label Name="templateLstBxExpanderHeader"
                                 Content="{Binding Path=Name}"
                                 FontWeight="Bold" />
                        </StackPanel>
                      </Expander.Header>
                      <ItemsPresenter />
                    </Expander>
                  </ControlTemplate>
                </Setter.Value>
              </Setter>
            </Style>
          </GroupStyle.ContainerStyle>
        </GroupStyle>
      </ListBox.GroupStyle>
    </ListBox>
  </Grid>
</Window>

XAML.cs:

using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace WpfApplication8
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public static readonly DependencyProperty sampleProperty = DependencyProperty.Register(
        "Samples", typeof(ObservableCollection<sample>), typeof(MainWindow), new PropertyMetadata(new ObservableCollection<sample>()));

    public ObservableCollection<sample> Samples
    {
        get
        {
            return (ObservableCollection<sample>)this.GetValue(sampleProperty);
        }

        set
        {
            this.SetValue(sampleProperty, value);
        }
    }      

    public MainWindow()
    {
        this.InitializeComponent();

         CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lstbx.ItemsSource);
        PropertyGroupDescription groupDescription = new PropertyGroupDescription("Location");
        view.GroupDescriptions.Add(groupDescription);      
        sample test = new sample();
        test.Location = "one";
        test.Name = "blah blah";
        Samples.Add(test);
        sample test2 = new sample();
        test2.Location = "two";
        test2.Name = "ya ya";
        Samples.Add(test2);

    }
}
}

样例.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplication8
{
public class sample
{


    public string Name { set; get; }
    public string Location{ set; get; }

}

你对这个有什么想法? - user892381
2
我已经使用VS 2015检查了这个示例,并且AutomationProperties已经正确设置 - 我已经使用WPF Snoop检查了它们。我认为问题不在于AutomationProperties,而是在于用于检查它们的软件上。一些由Microsoft提供和推荐的工具无法正确读取它们(我不记得名字了)- 我的团队几个月前就遇到过这样的问题。 - Maciek Świszczowski
AutomationProperties 类:提供了一种获取或设置 AutomationPeer 元素实例的关联属性值的方法。它不适用于标准 WPF 控件。对于 ListBox,有 ListBoxAutomationPeer 类。 - AnjumSKhan
这实际上取决于您使用的屏幕阅读器,人们一直在说Windows中的本机屏幕阅读器(Narrator,最有可能是您正在使用的)与其他专有屏幕阅读器相比非常有限,这可能是问题的根源。 - SamTh3D3v
我还没有进行测试,但建议尝试使用<StackPanel IsItemHost="True" />代替<ItemsPresenter />,因为我在使用Windows屏幕阅读器时遇到了问题,显然它无法读取<ItemsPresenter>中的内容。我花了几天时间才弄清楚这个问题。 - IronHide
3个回答

1
这个问题实际上是关于屏幕阅读器如何获取值的。通过MSAA,组项可以从光标处访问,但无法通过UIA访问。在WPF中,UIA是主要的可访问性API。
UIA和WPF的核心问题在于,尝试读取由光标发现的控件(其他方式是焦点和插入符),通常会返回主窗口而不是控件本身。
作为一个屏幕阅读器的开发者,最好的处理方法是同时使用MSAA和UIA。如果UIA没有返回有价值的东西,则回退到使用MSAA。

0

尝试在Name旁边设置AutomationProperties.HelpText


-1
你可以使用 DisplayMemberPath="Name":
    <ListBox x:Name="lstbx" Margin="71,45,99,78" ItemsSource="{Binding ElementName=win, Path=Samples}" DisplayMemberPath="Name" >

enter image description here

或者您可以使用.ToString()

public class sample
{
    public string Name { set; get; }

    public string Location { set; get; }

    public override string ToString()
    {
        return Name;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接