我有一个WPF应用程序,需要支持屏幕阅读器(特别是JAWS)。问题是,当列表视图项发生更改(添加、删除)时,JAWS不会发布任何消息。盲人用户完全不知道发生了什么。当试图在列表视图控件中添加/删除项目时,有没有办法强制屏幕阅读器声明一些文本?我该怎么做呢?
发布于 2013-07-17 14:26:12
如果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");发布于 2015-12-05 14:24:26
JAWS只会对获得焦点的控件做出响应。我在我的应用程序中需要类似的功能,并通过以下方式解决了它。
public class AccessibilityMessage { private AccessibilityMessage(对象发送方,字符串消息,双延迟){ DispatcherTimer sleep = new DispatcherTimer();int counter = 3;try { if (accessibilityMessageAudibleControl != null && accessibilityMessageSilentControl != null) { sleep.Interval = TimeSpan.FromMilliseconds( delay);//更新消息。accessibilityMessageAudibleControl.SetValue(AutomationProperties.NameProperty,消息);//将焦点放在静默控件上。accessibilityMessageSilentControl.IsTabStop = true;accessibilityMessageSilentControl.Focus();//将焦点置于消息上。accessibilityMessageAudibleControl.IsTabStop = true;accessibilityMessageAudibleControl.Focus();//使用计时器模拟睡眠。我们需要短暂的暂停,以便给屏幕阅读器足够的时间//来处理消息控件上的焦点。在短暂的//暂停之后,我们将焦点返回到原始控件。如果我们不像//这样暂停,屏幕阅读器将不会可靠地对消息做出反应。sleep.Tick += (s,e) => { counter--;//检查是否可以将焦点放在原始控件上。if (counter == 0) { //将焦点返回到触发消息的原始控件。if (sender != null && sender is Control) { //将焦点返回到原始控件。((控制)发送者).Focus();} //退出计时器。sleep.Stop();//通知监听器消息已经发布。if (宣告!= null)宣告(this,null);} };//开始计时。sleep.Start();} else {抛出新的异常(“辅助功能消息控件未在应用程序管理器中定义。无法公告辅助功能消息。“);}} catch (Exception ex) { ErrorDialog.Show(ex,sender);}}公共事件消息公告;public静态消息公告(object AccessibilityMessage,string message,double AccessibilityMessage= 250) { return new AccessibilityMessage(sender,message,delay);}}
发出通知,通知用户正在加载数据网格,请稍候。
//将myGrid作为发送方传递,以便在公告之后接收焦点。ApplicationManager.AccessibilityMessage.Announce(myGrid,“正在加载采购订单表,请稍候。”).Announced += (s,arg) => { //调用WEB服务检索数据。新服务= DataService DataService();svc.ListPurchasOrdersCompleted += OnListPurchaseOrders_Completed();svc.ListPurchaseOrders();};
宣布数据已加载到数据网格中。
private void OnListPurchaseOrders_Completed(object sender,AsyncCompletedEventArgs e) { try { if (e.Error == null) { myGrid.ItemsSource = e.Result();//传入myGrid作为发送方,以便在通知后接收焦点。AccessibilityMessage.Announce(myGrid,string.Format(“已将{0}个订单加载到采购订单表中。”,myGrid.Items.Count));} else {抛出e.Error;}} catch (Exception ex) { ErrorDialog.Show(ex,this);} }
通过使用它,您可以随时发布公告,只需使用宣告()调用即可。我最初是为Silverlight实现的。它也应该适用于WPF。
发布于 2018-09-26 13:16:34
我喜欢的方式是在UI中有一个高度为0的TextBlock:
<TextBlock
x:Name="screenReaderText"
Height="0"
AutomationProperties.LiveSetting="Assertive" />然后,我使用此方法让它读取一些内容:
public void ReadTextToScreenReader(string text)
{
var peer = UIElementAutomationPeer.FromElement(this.screenReaderText);
if (peer != null)
{
this.screenReaderText.Text = text;
peer.RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
}
}它基本上是在说:“看,这个控件改变了内容,最好把它读出来。”
https://stackoverflow.com/questions/17541761
复制相似问题