本文介绍了如何使屏幕阅读器阅读WPF消息的方式类似于阅读Win32 MessageBox?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个WPF桌面应用程序,它需要显示一些自定义消息窗口.我很难让屏幕阅读器(例如Freedom Scientific的JAWS)正确朗读它们.

We have a WPF desktop application which needs to show some custom message windows. I am having trouble getting them to be read aloud properly by screen readers such as JAWS from Freedom Scientific.

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

I want to achieve the same behavior as when showing a system message box. For comparison, System.Windows.MessageBox.Show("my message", "My Caption); is announced by JAWS as "My caption dialog. My message. OK Button". This is perfect.

打开我的消息窗口(仅包含TextBlock和OK Button)时,将宣布窗口标题,并宣布OK按钮具有焦点,但未宣布TextBlock消息.

When my message windows are opened (containing only a TextBlock and OK Button), the window title is announced and the OK button is announced as having focus but the TextBlock message is not announced.

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

Here's a simple test application which shows the issue. Our real app has icons and other status text, of course.

<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>

当我使用以下方法显示此内容时:

When I show this using:

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

屏幕阅读器会宣布:"MyMessageBox.关闭按钮" ,因此它不会像系统消息框那样读取TextBlock.

The screen reader announces: "MyMessageBox. Close Button" so it's not reading the TextBlock like the system message box does.

使用Windows SDK inspectaccevent工具发现的是

What I've found using the Windows SDK inspect and accevent tools is that

  • The system message box accessibility type is 'Dialog' but the WPF dialog's accessibility type is 'Window'. This might matter. There is no UI Automation Control Type of Dialog https://msdn.microsoft.com/en-us/library/ms749005(v=vs.110).aspx . Is this a bug or limitation in WPF perhaps?

我尝试在窗口上设置各种'AutomationProperties'附加属性,以使AutomationPeer具有更好的信息,但在ShowDialog运行时不会读取任何信息.

I have tried setting various 'AutomationProperties' attached properties on my window so that the AutomationPeer will have better info but none of those are read when the ShowDialog runs.

由于TextBlock无法获得输入焦点,因此甚至无法通过制表键读取文本.我暂时使用只读的TextBox来获取焦点,但是体验仍然是错误的,我们的盲人用户不必为了阅读简单的状态消息而四处浏览.

Since TextBlock cannot receive input focus, there's no way to even get the text read by tabbing. I temporarily use a read-only TextBox instead to get focus but the experience is still wrong and our blind users should not have to tab around just to have a simple status message read to them.

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

As part of the experimenting, I also tried creating my own derived AutomationPeer for the message window but none of the Core method content is read automatically when the dialog is launched. The automation child list does have the title bar object listed as the first child whereas that's the last child for the system message box though I don't see a way to change that right now.

对于创建基于WPF的自定义消息框并为盲人用户提供完全适当访问权限的任何帮助,我将不胜感激.

I'd greatly appreciate any help for creating a WPF-based custommessage box with full, proper accessibility for blind users.

推荐答案

您必须告诉自动化API您的Window是一个MessageBox.为此,请将此代码添加到您的窗口中

You have to tell the automation API that your Window is a MessageBox.To do that add this code to your Window

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

并将此类添加到您的项目中

and add this class to your project

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

因为我们不需要在应用程序中进行本地化,所以"DialogFeld"是德语本地化控件类型.本地化这一部分是您必须自己了解的部分. ;-)

As we don't need localization in our app "DialogFeld" is the german localized control type. Localizing that one is the part you would have to find out by yourself. ;-)

这篇关于如何使屏幕阅读器阅读WPF消息的方式类似于阅读Win32 MessageBox?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 16:34