如何让屏幕阅读器读取我的WPF消息,类似于他们如何阅读Win32 MessageBox?

时间:2017-01-06 13:41:19

标签: c# wpf xaml jaws-screen-reader section508

我们有一个WPF桌面应用程序需要显示一些自定义消息窗口。我无法通过自由科学的JAWS等屏幕阅读器正确朗读它们。

我希望实现与显示系统消息框时相同的行为。为了进行比较,JAWS将System.Windows.MessageBox.Show("my message", "My Caption);宣布为"我的标题对话框。我的留言确定按钮" 。这很完美。

当我的消息窗口打开时(仅包含TextBlock和OK Button),窗口标题被宣布,OK​​按钮被宣布为具有焦点,但TextBlock消息是没有宣布。

这是一个显示问题的简单测试应用程序。我们的真实应用程序当然有图标和其他状态文本。

<Window x:Class="Jaws_MessageBox_Test.MyMessageBox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Jaws_MessageBox_Test"
        mc:Ignorable="d"
        Title="MyMessageBox" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock x:Name="mainLabel" Grid.Row="0">Hi there, this is a test to see if JAWS will read the main textbloc when shown.</TextBlock>
        <Button Grid.Row="1" Margin="5" HorizontalAlignment="Right" Padding="10,0,10,0"  IsDefault="True" x:Name="closeButton" Click="closeButton_Click">_Close</Button>
    </Grid>
</Window>

当我使用时显示:

var mb = new MyMessageBox();
mb.ShowDialog();

屏幕阅读器宣布:&#34; MyMessageBox。关闭按钮&#34; 所以它不像系统消息框那样读取TextBlock。

我使用Windows SDK inspectaccevent工具找到的是

  • 系统消息框辅助功能类型是&#39;对话框&#39;但是WPF对话框的辅助功能类型是“窗口”。这可能很重要。对话框https://msdn.microsoft.com/en-us/library/ms749005(v=vs.110).aspx没有UI自动控制类型。这可能是WPF中的错误或限制吗?

  • 我尝试过设置各种自动化属性&#39;我的窗口上附加了属性,以便AutomationPeer有更好的信息,但ShowDialog运行时不会读取这些信息。

  • 由于TextBlock无法接收输入焦点,因此无法通过标签阅读文本。我暂时使用只读TextBox来获得焦点,但体验仍然是错误的,我们的盲人用户不应该只是为了向他们读取简单的状态信息。

  • 作为实验的一部分,我还尝试为消息窗口创建自己的派生AutomationPeer,但在启动对话框时,不会自动读取Core方法内容。自动化子列表确实将标题栏对象列为第一个孩子,而这是系统消息框的最后一个孩子,尽管我现在还没有找到改变它的方法。

    < / LI>

我非常感谢您为创建基于WPF的自定义消息框提供任何帮助,并为盲人用户提供完全,适当的可访问性。

5 个答案:

答案 0 :(得分:3)

您必须告诉自动化API您的Window是MessageBox。 为此,请将此代码添加到您的Window

protected override AutomationPeer OnCreateAutomationPeer()
{
    return new MessageBoxWindowAutomationPeer(this);
}

并将此课程添加到您的项目中

public class MessageBoxWindowAutomationPeer : WindowAutomationPeer
{
    private const string WC_DIALOG = "#32770";

    public MessageBoxWindowAutomationPeer(Window owner)
        : base(owner)
    {
    }

    protected override string GetClassNameCore()
    {
        return WC_DIALOG;
    }

    protected override string GetLocalizedControlTypeCore()
    {
        return "Dialogfeld";
    }

    protected override bool IsContentElementCore()
    {
        return true;
    }

    protected override bool IsControlElementCore()
    {
        return true;
    }
}

因为我们不需要在我们的应用程序中进行本地化&#34; DialogFeld&#34;是德国本地化控制类型。本地化一个是您必须自己找到的部分。 ; - )

答案 1 :(得分:1)

在Textblock

内的运行中设置AutomationProperties.HelpText

所以例如:

<TextBlock>
    <Run Text="aTextString" AutomationProperties.HelpText="ATextString"/>
</TextBlock>

<TextBlock>
    <Run Text="aTextString" AutomationProperties.HelpText="{Binding Text, RelativeSource={RelativeSource self}}"/>
</TextBlock>

答案 2 :(得分:0)

好好阅读问题是Jaws不是WPF,因为它往往不会读取Labels和TextBlocks上的静态文本 - 奇怪的行为。

解决方法可能是使用TextBox,设置BorderStyle = None并在其上放置一个矩形,fill = White,Opacity = 0.01。这将阻止用户专注于TextBox,意味着文本不会是静态的,而Jaws应该自动读取文本。 。

答案 3 :(得分:0)

有一件事,它是否必须是Jaws读取你的应用程序弹出的对话框?

你有没有看过使用system.speech.synthesis.speechsynthesizer在弹出对话框时说出文字 - 只是想一想!

答案 4 :(得分:0)

我不知道这是否是正确的解决方案,但这可以在JAWS 18上正常运行。

<Window ...>
<UserControl>
    <StackPanel>
        <TextBlock Name="MessageText" ... />
        <Button Name="OKButton" ...../>
    </StackPanel>
</UserControl>
</Window>

,然后在加载窗口时聚焦按钮。 因此,我将stackpanel包装在usercontrol元素内。