事件处理程序如何自动提升自身?

时间:2014-11-23 12:14:47

标签: c# wpf

我的WPF格式中有两个按钮,即播放和转发。播放按钮读取在TextBox中输入的文本但不能突出显示句子。另一方面,前进按钮可以突出显示每次按下时在TextBox中输入的文本的一个句子。

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

我不知道如何以编程方式单独提升前进按钮事件处理程序

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

1 个答案:

答案 0 :(得分: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;
}

<强>&LT;编辑&gt; 我进行了一些测试,似乎SpeakAsyncCancelAll()方法不会干扰后续调用Speak()方法。另外,我发现它 取消同步语音操作(即它会中断正在进行的Speak()调用)。所以上面应该可以正常工作,你甚至可以添加一个单独的按钮来取消操作,只需设置一个标志然后调用SpeakAsyncCancelAll()来中断当前的语音操作。
&LT; /编辑&gt;

长期来看,一个更好的解决方案是在async类周围实现一个真正的SpeechSynthesizer - 支持包装器。不幸的是,尽管我可以说,语音合成的唯一内置实现直接支持async / awaitSpeechSynthesizer类的Windows Phone版本。但是您应该能够编写自己的包装器,使用TaskCompletionSource以及处理各种SpeechSynthesizer事件,以允许适合async / await范例的异步方法。 / p>

请注意,在上面的内容中,我禁用了该按钮,以便在处理上一个按钮时再次引发该事件。您不希望此代码具有并发迭代,因此我依靠UI状态来阻止重新输入。

最后请注意,上述内容并未为用户提供任何中断循环文本选择进度的方法。你没有在原始问题中提供足够的上下文来了解它是如何工作的,所以我把它留了出来。但正如我上面提到的,你可以使用SpeakAsyncCancelAll()方法中断同步语音操作,所以这就像设置上面提到的标志一样简单,调用cancel方法,然后在上面的循环中检查看看你是否需要提早爆发。