2013-07-09 4 views
7

私はスクリーンリーダー(特にJAWS)をサポートするWPFアプリケーションを持っています。問題は、リストビュー項目が変更(追加、削除)されたときに、JAWSは何も発表しないことです。視覚障害のあるユーザーは、何が起こったのか全く分かりません。リストビューコントロールからアイテムを追加/削除しようとすると、スクリーンリーダーがテキストを発表するように強制する方法はありますか?それをどうすればいいのですか?リストビュー(WPF)の項目が変更されたときに、スクリーンリーダー(JAWS)がカスタムテキストを表示するにはどうすればよいですか?

+0

新しいアイテムに集中してみるとよいでしょう。通常、ナレータ/アクセシビリティツールは、焦点を絞ったものだけを読み込みます。 – AndrewS

答えて

3

JAWSリーダーがこの機能をサポートしていない場合は、SpeechSynthesizerで自分で実装できます。例えば、音声再生:

using System.Speech.Synthesis; 

SpeechSynthesizer MySpeechSynthesizer = new SpeechSynthesizer(); 
MySpeechSynthesizer.Speak("Hello!"); 

私はListBoxが割り当てられObservableCollectionの例を使用しました。 ObservableCollectionがイベントCollectionChangedである、という点で収集 [MSDN]上で実行される動作の列挙が含まれています

Member name Description 
------------ ------------ 
Add   One or more items were added to the collection. 
Move   One or more items were moved within the collection. 
Remove  One or more items were removed from the collection. 
Replace  One or more items were replaced in the collection. 
Reset   The content of the collection changed dramatically. 

このeventはこのように実装されます。

以下
// Set the ItemsSource 
SampleListBox.ItemsSource = SomeListBoxCollection; 

// Set handler on the collection 
SomeListBoxCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(SomeListBoxCollection_CollectionChanged); 

private void SomeListBoxCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    if (e.Action == NotifyCollectionChangedAction.Add) 
    { 
     // Some actions, in our case - speech 
    } 
} 

は私の例です:

XAML

<Window x:Class="JAWShelp.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" 
    WindowStartupLocation="CenterScreen"> 

    <Grid> 
     <ListBox Name="MyListBox" DisplayMemberPath="Name" SelectedIndex="0" Width="100" Height="100" Loaded="MyListBox_Loaded" /> 

     <WrapPanel Width="200" Height="30" Margin="40,150,0,0"> 
      <Button Name="AddButton" Padding="5" Content="Add item" VerticalAlignment="Bottom" Click="AddButton_Click" /> 
      <Button Name="RemoveButton" Padding="5" Margin="30,0,0,0" Content="Remove item" VerticalAlignment="Bottom" Click="RemoveButton_Click" /> 
     </WrapPanel> 
    </Grid> 
</Window> 
問題なく

Code behind

// using System.Speech.Synthesis; 
// using System.Collections.ObjectModel; 
// using System.Collections.Specialized; 

public partial class MainWindow : Window 
{ 
    public class Person 
    { 
     public string Name 
     { 
      get; 
      set; 
     } 
    } 

    private ObservableCollection<Person> DataForListBox = new ObservableCollection<Person>(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void MyListBox_Loaded(object sender, RoutedEventArgs e) 
    { 
     DataForListBox.Add(new Person() 
     { 
      Name = "Peter Orange",     
     }); 

     MyListBox.ItemsSource = DataForListBox; 

     DataForListBox.CollectionChanged += new NotifyCollectionChangedEventHandler(DataForListBox_CollectionChanged); 
    } 

    private void DataForListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      SpeechSynthesizer MySpeechSynthesizer = new SpeechSynthesizer(); 

      MySpeechSynthesizer.Speak("You are add item."); 
     } 

     if (e.Action == NotifyCollectionChangedAction.Remove) 
     { 
      SpeechSynthesizer MySpeechSynthesizer = new SpeechSynthesizer(); 

      MySpeechSynthesizer.Speak("You are remove item."); 
     } 
    } 

    private void AddButton_Click(object sender, RoutedEventArgs e) 
    { 
     DataForListBox.Add(new Person() 
     { 
      Name = "Jack Rider", 
     }); 
    } 

    private void RemoveButton_Click(object sender, RoutedEventArgs e) 
    { 
     DataForListBox.RemoveAt(1); 
    } 
} 

、あなたはAdd/Removeアイテムの再生、テキストを追加することができます。またPromptBuilderを使用してプレイ.wavファイルを追加することができます。

PromptBuilder MyPromptBuilder = new PromptBuilder(); 

MyPromptBuilder.AppendAudio("SomeFile.wav"); 
+0

ありがとうございます。 JAWSがこのテキストを発表したいと思います。 –

3

JAWSのみフォーカスを得るコントロールに対応します。私は自分のアプリケーションに同様の機能が必要で、以下のように解決しました。

  1. レイアウトに2つの非表示のテキストボックスコントロールを追加します。

    <!--Controls used to announce accessibility messages for screen readers.--> 
    <TextBox x:Name="ATMessage_Silent" Height="1" Width="1" IsTabStop="False" AutomationProperties.Name=" "/> 
    <TextBox x:Name="ATMessage_Audible" Height="1" Width="1" IsTabStop="False"/> 
    
  2. メッセージをアナウンスするクラスを追加します。私はそれを信頼できるものにするために、複数のコントロール間でフォーカスを合間させることを一時的に中断する必要があることを発見しました。それ以外の場合、JAWSは確実にメッセージをアナウンスしません。

    public class AccessibilityMessage 
    { 
        private AccessibilityMessage(object sender, string message, double delay) 
        { 
         DispatcherTimer sleep = new DispatcherTimer(); 
         int counter = 3; 
    
         try 
         { 
          if (accessibilityMessageAudibleControl != null && accessibilityMessageSilentControl != null) 
          { 
           sleep.Interval = TimeSpan.FromMilliseconds(delay); 
    
           // Update the message. 
           accessibilityMessageAudibleControl.SetValue(AutomationProperties.NameProperty, message); 
    
           // Give focus to the silent control. 
           accessibilityMessageSilentControl.IsTabStop = true; 
           accessibilityMessageSilentControl.Focus(); 
    
           // Give focus to the message. 
           accessibilityMessageAudibleControl.IsTabStop = true; 
           accessibilityMessageAudibleControl.Focus(); 
    
           // Use a timer to simulate a sleep. We need to pause briefly to give enough time 
           // for the screen reader to process the focus on the message control. After a brief 
           // pause we will give focus back to the original control. If we do not pause like 
           // this the screen reader will not reliably react to the message. 
           sleep.Tick += (s, e) => 
           { 
            counter--; 
    
            // Check to see if it is time to focus the original control. 
            if (counter == 0) 
            { 
             // Return focus to the original control that triggered the message. 
             if (sender != null && sender is Control) 
             { 
              // Give focus back to the original control. 
              ((Control)sender).Focus(); 
             } 
    
             // Exit the timer. 
             sleep.Stop(); 
    
             // Inform any listeners the message has been announced. 
             if (Announced != null) 
              Announced(this, null); 
            } 
           }; 
    
           // Start the time. 
           sleep.Start(); 
          } 
          else 
          { 
           throw new Exception("Accessibility message controls are not defined in the Application Manager. Unable to announce accessibility message."); 
          } 
         } 
         catch (Exception ex) 
         { 
          ErrorDialog.Show(ex, sender); 
         } 
        } 
    
        public event EventHandler Announced; 
    
        public static AccessibilityMessage Announce(object sender, string message, double delay = 250) 
        { 
         return new AccessibilityMessage(sender, message, delay); 
        } 
    } 
    
  3. メッセージをお知らせください。単にアナウンスメントをするか、発表されたイベントを使って発表することができます。アナウンスメント後に追加作業を行うことができます。

    データグリッドにデータが読み込まれている間、お待ちください。

    // Pass myGrid as the sender so it will receive focus after the announcement. 
    ApplicationManager.AccessibilityMessage.Announce(myGrid, "Loading purchase orders table, please wait.").Announced += (s, arg) => 
    { 
        // MAKE WEB SERVICE CALL TO RETRIEVE DATA. 
        DataService svc = new DataService(); 
        svc.ListPurchasOrdersCompleted += OnListPurchaseOrders_Completed(); 
        svc.ListPurchaseOrders(); 
    }; 
    

    データグリッドにデータが読み込まれたことをアナウンスします。これを使用する

    private void OnListPurchaseOrders_Completed(object sender, AsyncCompletedEventArgs e) 
    { 
        try 
        { 
         if (e.Error == null) 
         { 
          myGrid.ItemsSource = e.Result(); 
    
          // Pass myGrid as the sender so it will receive focus after the announcement. 
          AccessibilityMessage.Announce(myGrid, string.Format("Loaded {0} orders into the purchase orders table.", myGrid.Items.Count)); 
         } 
         else 
         { 
          throw e.Error; 
         } 
        } 
        catch (Exception ex) 
        { 
         ErrorDialog.Show(ex, this); 
        } 
    } 
    

あなたは、単にアナウンス()呼び出しを使って、いつでもあなたはアナウンスを行うことができます。もともと私はこれをSilverlightに実装しました。 WPFでも同様に動作します。

+0

ありがとうエリック、それは私のためにうまく動作します。 –

関連する問題