为了澄清我关于使用Prompt 类来保存您需要的任何标识状态的评论,请考虑以下内容,其中Prompt
保存了对 source 的引用TextBox
。
Imports System.Speech.Synthesis
Public Class MyPrompt : Inherits Prompt
Private tbRef As WeakReference(Of TextBox)
Public Sub New(textBox As TextBox)
MyBase.New(textBox.Text)
' only hold a weak reference to the TextBox
' to avoid any disposal issues
tbRef = New WeakReference(Of TextBox)(textBox)
End Sub
Public ReadOnly Property SourceTextBox As TextBox
Get
Dim ret As TextBox = Nothing
tbRef.TryGetTarget(ret)
Return ret
End Get
End Property
End Class
现在您的原始代码可以写成:
Imports System.Speech.Synthesis
Public Class Form1
Private WithEvents _Synth As New SpeechSynthesizer
Private Sub TextBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
' use a custom prompt to store the TextBox
_Synth.SpeakAsync(New MyPrompt(Me.TextBox1))
End If
End Sub
Private Sub _Synth_SpeakProgress(sender As Object, e As SpeakProgressEventArgs) Handles _Synth.SpeakProgress
Dim mp As MyPrompt = TryCast(e.Prompt, MyPrompt)
If mp IsNot Nothing Then
Dim tb As TextBox = mp.SourceTextBox
If tb IsNot Nothing Then
' set the selection in the source TextBox
tb.SelectionStart = e.CharacterPosition
tb.SelectionLength = e.CharacterCount
End If
End If
End Sub
End Class
编辑:
OP 希望将其与SpeakSsmlAsync 方法一起使用。这本身是不可能的,因为该方法Prompt
使用Prompt(String, SynthesisTextFormat) 构造函数创建了一个基础,并Prompt
在调用SpeechSynthesizer.SpeakAsync(created_prompt)
.
下面是一个派生Prompt
类,它接受 ssml 字符串或PromptBuilder 实例以及整数标识符。新版本的 MyPrompt 使用 ssml 和整数标识符。
Imports System.Speech.Synthesis
Public Class MyPromptV2 : Inherits Prompt
Public Sub New(ssml As String, identifier As Int32)
MyBase.New(ssml, SynthesisTextFormat.Ssml)
Me.Identifier = identifier
End Sub
Public Sub New(builder As PromptBuilder, identifier As Int32)
MyBase.New(builder)
Me.Identifier = identifier
End Sub
Public ReadOnly Property Identifier As Int32
End Class
...
Imports System.Speech.Synthesis
Public Class Form1
Private WithEvents _Synth As New SpeechSynthesizer
Private Sub TextBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
' build some ssml from the text
Dim pb As New PromptBuilder
pb.AppendText(TextBox1.Text)
' use ssml and and integer
_Synth.SpeakAsync(New MyPrompt(pb.ToXml, 10))
' or
'_Synth.SpeakAsync(New MyPrompt(pb, 10))
End If
End Sub
Private Sub _Synth_SpeakProgress(sender As Object, e As SpeakProgressEventArgs) Handles _Synth.SpeakProgress
Dim mp As MyPromptV2 = TryCast(e.Prompt, MyPromptV2)
If mp IsNot Nothing Then
Select Case mp.Identifier
Case 10
TextBox1.SelectionStart = e.CharacterPosition
TextBox1.SelectionLength = e.CharacterCount
End Select
End If
End Sub
End Class