2017-01-06 13 views
2

У нас есть настольное приложение WPF, которое должно отображать некоторые пользовательские окна сообщений. У меня возникают проблемы с тем, чтобы их читать вслух должным образом читателями экрана, такими как JAWS от Freedom Scientific.Как заставить читатели экрана читать мое сообщение WPF так же, как они читают Win32 MessageBox?

Я хочу добиться такого же поведения, как при отображении системного сообщения. Для сравнения, System.Windows.MessageBox.Show("my message", "My Caption); анонсируется JAWS как «Диалоговое окно« Моя подпись ».« OK »«. Это потрясающе.

Когда мои окна сообщений открываются (содержит только TextBlock и ОК Button), заголовок окна объявляется и кнопка ОК объявляется фокусом, но сообщение 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(); 

Читатель экрана объявляет: «MyMessageBox Закрыть Кнопка» так что не читает TextBlock как окна системных сообщений делает.

Что я нашел с помощью Windows SDK inspect и accevent инструментов является то, что

  • Система сообщений коробчатого типа доступность «Диалог», но тип доступности для диалога WPF является «Window». Это может иметь значение. Нет типа интерфейса управления автоматизацией UI https://msdn.microsoft.com/en-us/library/ms749005(v=vs.110).aspx. Возможно, это ошибка или ограничение в WPF?

  • Я попытался установить в моем окне дополнительные свойства «AutomationProperties», чтобы AutomationPeer получил лучшую информацию, но ни один из них не читается при запуске ShowDialog.

  • Поскольку TextBlock не может получать фокус ввода, нет возможности даже получить текст, читаемый путем табуляции. Я временно использую только для чтения TextBox, чтобы получить фокус, но опыт по-прежнему не так, и наши слепые пользователи не должны заходить на сайт только для того, чтобы им было прочитано простое сообщение о состоянии.

  • В качестве части эксперимента я также попытался создать собственное производное AutomationPeer для окна сообщений, но ни один из содержимого метода Core не будет автоматически прочитан при запуске диалога. В дочернем списке автоматизации есть объект строки заголовка, указанный в качестве первого дочернего элемента, тогда как это последний дочерний элемент для окна системного сообщения, хотя я не вижу способа изменить это прямо сейчас.

Я бы очень признателен за любую помощь в создании окна для проверки подлинности на основе WPF с полной доступностью для слепых пользователей.

ответ

3

Вы должны сообщить API автоматизации, что ваше Окно является MessageBox. Для этого добавьте этот код в окно

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

Как нам не нужна локализация в нашем приложении «DialogFeld» является немецким локализованы типа управления , Локализация этой части - это то, что вам нужно будет выяснить самостоятельно. ;-)

+0

Интересно! Я не думал использовать это для имени класса. Пытаясь это сделать, он автоматически не считывает первый элемент, как в случае с сообщениями с сообщениями ОС. Он читает их для вас? Возможно, мне тоже нужно изменить мой TextBlock. – jschroedl

+0

Я только пробовал его с NVDA, и там он работает, не нужно ничего менять в вашем диалоговом окне xaml. Будет проверять его с помощью JAWS и сообщать о моих выводах. Это займет несколько недель, так как я сейчас очень занят. – batzen

+0

Я много пробовал, но мне не удалось выяснить, что нужно сделать, чтобы заставить JAWS прочитать содержимое диалогового окна. Возможно, вы должны спросить компанию за JAWS, как они обнаруживают диалоги. Мне пришлось удалить JAWS, потому что он вызывает значительное замедление на моей машине. – batzen

0

Установите AutomationProperties.HelpText на бегу внутри TextBlock

Так для примера:

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

или

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

Я пробовал это и просто попробовал снова, чтобы быть уверенным. К сожалению, текст HelpText не читается, когда отображается диалог. Как бы я хотел. Он читает только заголовок окна, а затем текст объекта фокусировки (кнопка «Закрыть»). Кажется, что мне нужно установить в окне, чтобы сообщить читателям, что это диалог, и перед чтением текста объекта фокусировки есть интересный текст для чтения. – jschroedl

0

OK от чтения вокруг проблемы с Челюсти не WPF, как правило, не читать статический текст на ярлыках и текстовых блоках - странное поведение.

Обходным решением может быть использование TextBox, установка BorderStyle = None и размещение на нем прямоугольника, с fill = White, Opacity = 0.01. Это заставит пользователя сосредоточиться на TextBox и означает, что текст не будет статическим, а челюсти должны автоматически читать текст. , ,

+0

В настоящее время я использую ReadOnly TextBox, аналогичный тому, что вы описываете. Я начинаю думать, что это ограничение WPF, поскольку, похоже, не существует способа идентифицировать окно на основе WPF как «Диалог» для чтения с экрана. Если бы я мог, я думаю, что он будет искать исходный ярлык .... или, возможно, он вызывает событие доступности, которое заставляет текст читать. Настолько разочаровывающе ... – jschroedl

0

Одна вещь, это должны быть Челюсти, которые читают Диалоги, которые появляется в вашем приложении?

Вы посмотрели на использование system.speech.synthesis.speechsynthesizer, чтобы говорить текст при появлении диалога - просто мысль!

+0

Наши клиенты используют челюсти, поэтому я исследую, почему наше приложение не имеет сообщений, но другие делают. Остальные - это приложения Win32, а не WPF, как я считаю, это проблема. – jschroedl