2014-11-23 83 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

相關問題