如何让WPF中UserControl内的TextBlock被讲述人(Narrator)朗读?
WPF中让讲述人朗读UserControl内TextBlock的替代方案
针对UserControl模板内TextBlock无法被系统讲述人(Narrator)朗读的问题,除了改用样式模拟标签的Button外,还有以下几种可行方案:
方案1:将UserControl的自动化属性绑定到TextBlock内容
通过设置UserControl的AutomationProperties.Name,绑定到内部TextBlock的文本内容,让讲述人识别UserControl时朗读该文本:
<UserControl AutomationProperties.Name="{Binding ElementName=TestTextBlock, Path=Text}" AutomationProperties.AutomationId="Test_Control"> <UserControl.Template> <ControlTemplate> <TextBlock x:Name="TestTextBlock" Text="Test text" Focusable="True" /> </ControlTemplate> </UserControl.Template> </UserControl>
方案2:显式设置TextBlock的自动化属性
给TextBlock指定明确的自动化角色和名称,帮助讲述人识别其为可朗读文本元素:
<UserControl.Template> <ControlTemplate> <TextBlock Text="Test text" Focusable="True" AutomationProperties.AutomationId="Test_text" AutomationProperties.Name="Test text" AutomationProperties.Role="Text" /> </ControlTemplate> </UserControl.Template>
方案3:自定义UserControl的自动化对等类
通过后台代码实现自定义自动化对等类,让UserControl返回内部TextBlock的文本作为自动化名称:
后台代码
public class CustomUserControl : UserControl { protected override AutomationPeer OnCreateAutomationPeer() { return new CustomUserControlAutomationPeer(this); } } public class CustomUserControlAutomationPeer : UserControlAutomationPeer { public CustomUserControlAutomationPeer(CustomUserControl owner) : base(owner) { } protected override string GetNameCore() { var textBlock = ((CustomUserControl)Owner).Template.FindName("TestTextBlock", ((CustomUserControl)Owner)) as TextBlock; return textBlock?.Text ?? base.GetNameCore(); } }
XAML使用
<local:CustomUserControl> <local:CustomUserControl.Template> <ControlTemplate> <TextBlock x:Name="TestTextBlock" Text="Test text" Focusable="True" /> </ControlTemplate> </local:CustomUserControl.Template> </local:CustomUserControl>
方案4:手动触发讲述人朗读
监听TextBlock的获取焦点事件,手动调用自动化API或语音合成类触发朗读:
XAML
<UserControl.Template> <ControlTemplate> <TextBlock x:Name="TestTextBlock" Text="Test text" Focusable="True" GotFocus="TestTextBlock_GotFocus" /> </ControlTemplate> </UserControl.Template>
后台代码
private void TestTextBlock_GotFocus(object sender, RoutedEventArgs e) { if (sender is TextBlock textBlock) { // 触发自动化焦点并朗读 var automationElement = System.Windows.Automation.AutomationElement.FromElement(textBlock); automationElement?.SetFocus(); // 或者直接使用语音合成 using (var synth = new System.Speech.Synthesis.SpeechSynthesizer()) { synth.Speak(textBlock.Text); } } }
内容的提问来源于stack exchange,提问作者meJustAndrew
相关产品推荐
相关产品推荐

