2014-11-23 84 views
-1

我有两个按钮在我的WPF形式,即播放和转发。播放按钮读取文本框中输入的文本,但不能突出显示句子。另一方面,前进按钮可以突出显示每次按下文本框中输入的文本的一个句子。事件处理程序如何自动提升自己?

我希望前进按钮事件处理程序在读取一个句子时自动引发。在这种情况下,前进按钮可以读取一个突出显示的句子,然后突出显示第二个句子并读取该句子等等。

我不知道如何编程本身

private void btnForward_Click(object sender, RoutedEventArgs e) 
{ 
    highlightText(); 
    synth.SpeakAsyncCancelAll(); 
    synth.SpeakAsync(textArea.SelectedText); 
    //here it should be raised automatically again 
} 
+0

当你没有再次点击时再次提高'Click'事件是没有意义的。但是,除了这一点,假设它确实有效,结果会是什么?第二句话将被*立即*选择,并且'synth。SpeakAsyncCancelAll()'会取消第一句。 'SpeakAsync'的全部重点是,在讲话完成之前,你的代码的执行会继续*。 – hvd 2014-11-23 12:30:08

+0

我认为第二句不会被_immediately_选中,因为'synth.SpeakAsync(textArea.SelectedText);'会导致事件等到它读取先前选择的句子。 – Hadi 2014-11-23 12:36:38

+1

不,它没有。再次,这是'... Async'函数的全部:'Speak'方法等待。 SpeakAsync方法不会等待。这也是在文档中提到的。你可以通过添加一行像MessageBox.Show(“...”);'来轻松看到,并检查你在演讲过程中还是之后都会收到一个消息框。 – hvd 2014-11-23 12:55:37

回答

0

提高前进按钮事件处理程序,如果我理解正确的问题,你希望用户必须按“前进”按钮只有一次。之后,程序应该自动继续前进文本选择,就像第一次按下按钮时一样,并为每个新选择的文本播放语音合成器。

如果是这样的话,我相信这个可能工作:

private async void btnForward_Click(object sender, RoutedEventArgs e) 
{ 
    btnForward.Enabled = false; 
    while (true) 
    { 
     highlightText(); 

     // NOTE: use whatever expression correctly identifies the state after 
     // you've called highlightText() when there's no more text to read. 
     // Here I've assumed that the selection will simply be empty, but 
     // if that's not right, presumably you have _some_ way to know that 
     // you're at the end of the text. 
     if (textArea.SelectedText == "") 
     { 
      break; 
     } 

     synth.SpeakAsyncCancelAll(); 
     await Task.Run(() => synth.Speak(textArea.SelectedText)); 
    } 
    btnForward.Enabled = true; 
} 

<编辑> 我跑一个小的测试,它似乎是在SpeakAsyncCancelAll()方法不以立即干预随后调用Speak()方法。另外,我发现确实取消了同步语音操作(即它会中断正在进行的对Speak()的呼叫)。所以上述应该可以正常工作,甚至可以添加一个单独的按钮来取消操作,只需设置一个标志,然后调用SpeakAsyncCancelAll()来中断当前的语音操作。
< /编辑>

从长期来看,一个更好的解决办法是实现上SpeechSynthesizer类真正async - 支持包装。不幸的是,据我所知,直接支持async/await的语音合成的唯一内置实现是SpeechSynthesizer类的Windows Phone版本。但是,您应该可以编写自己的包装,使用TaskCompletionSource以及处理各种SpeechSynthesizer事件,以允许符合范例的异步方法。

请注意,在上述情况下,我禁用了该按钮,以便在处理上一个按钮按下时不再引发该事件。您不希望此代码具有并发迭代,所以我依靠UI状态来防止重新进入。

最后要注意的是,以上内容并没有提供任何方式让用户中断通过文本选择循环的进度。你在原始问题中没有提供足够的背景知道如何工作,所以我只是把它排除在外。但正如我上面提到的,你可以使用SpeakAsyncCancelAll()方法中断同步语音操作,所以这会像设置一个标志那样简单,就像我上面提到的那样,调用cancel方法,然后在上面的循环中检查该标志以查看是否你需要提前爆发。

+0

基本上我正在写一个读取一些文本的程序。它还应该突出显示它正在阅读的每个句子。用户应该能够前进和后退。转发将突出显示并阅读下一句,而后退则反过来。 [这里](http://bdatech.org/what-technology/text-to-speech/)就是这样的软件的一个例子。 – Hadi 2014-11-25 12:09:34

+0

我的程序只能阅读每次播放按钮上的文本的一个句子,但不会前进。 – Hadi 2014-11-25 12:14:39

相关问题