Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 事件处理程序如何自动提升自身?_C#_Wpf - Fatal编程技术网

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

C# 事件处理程序如何自动提升自身?,c#,wpf,C#,Wpf,我有两个按钮在我的WPF形式,即播放和前进。“播放”按钮读取文本框中输入的文本,但不能突出显示句子。另一方面,“前进”按钮可以在每次按下时突出显示文本框中输入的文本的一句话 我希望forward按钮事件处理程序在读取一句话时自动启动。在这种情况下,“前进”按钮可以读取一个突出显示的句子,然后可以突出显示第二个句子并读取该句子,依此类推 我不知道如何通过编程自行提升forward按钮事件处理程序 private void btnForward_Click(object sender, Routed

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

我希望forward按钮事件处理程序在读取一句话时自动启动。在这种情况下,“前进”按钮可以读取一个突出显示的句子,然后可以突出显示第二个句子并读取该句子,依此类推

我不知道如何通过编程自行提升forward按钮事件处理程序

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

如果我理解正确,您希望用户只需按一次“前进”按钮。在这之后,程序将自动继续推进文本选择,就像第一次按下按钮一样,并为每个新选择的文本播放语音合成器

如果是这样的话,我相信这是可行的:

我运行了一个小测试,似乎
speakasyncancelall()
方法不会干扰对
Speak()
方法的后续调用。此外,我发现它确实会取消同步语音操作(即,它会中断对
Speak()
的正在进行的调用)。因此,上述操作肯定可以正常工作,您甚至可以添加一个单独的按钮来取消操作,只需设置一个标志,然后调用
speakasyncancelall()
来中断当前的语音操作。

从长远来看,更好的解决方案是围绕
SpeechSynthesizer
类实现真正的
异步
支持包装器。不幸的是,据我所知,唯一直接支持
async
/
wait
的语音合成内置实现是
SpeechSynthesizer
类的Windows Phone纯版本。但是,您应该能够使用
TaskCompletionSource
以及各种
SpeechSynthesizer
事件来编写自己的包装器,以允许适合
async
/
wait
范式的异步方法

请注意,在上面,我禁用了按钮,以便在处理上一次按钮按下时不会再次引发事件。您不希望此代码具有并发迭代,因此我依赖于UI状态来防止在此重新进入


最后要注意的是,上面没有为用户提供任何方式来中断文本选择循环的进程。在你最初的问题中,你没有提供足够的上下文来知道这将如何工作,所以我就把它省略了。但是正如我上面提到的,您可以使用
speakasyncancelall()
方法中断同步语音操作,因此这就像我上面提到的设置标志一样简单,调用cancel方法,然后在上面的循环中检查该标志,查看是否需要提前触发。

如果您没有再次实际单击,则再次引发
单击事件是没有意义的。但撇开这一点不谈,假设它真的起作用了,会有什么影响呢?将立即选择第二句话,
synth.speakasyncancelall()
将取消第一句话。
SpeakAsync
的全部要点是,在演讲结束之前,您的代码将继续执行。我认为不会立即选择第二句话,因为
synth.SpeakAsync(textArea.SelectedText)使事件等待,直到它读取以前选择的句子。否,它不会。同样,这就是
…Async
函数的全部要点:
Speak
方法等待。
SpeakAsync
方法不等待。文档中也提到了这一点。通过添加像
MessageBox.Show(“…”)这样的行,您可以很容易地看到这一点,并检查您是在演讲过程中还是演讲结束后收到消息框。谢谢。我注意到我错了。那么,你对如何完成我的工作有什么想法(如我的问题所述)?我认为基本想法应该是,你要听
SpeakCompleted
事件,当发生这种情况时,确定这是否是你的“前进”按钮的结果(这需要你跟踪哪个按钮处于“活动状态”),看看下面是否有一个句子,如果有,选择它并说出来。基本上我正在写一个程序来阅读一些文本。它还应该突出显示它正在阅读的每个句子。用户应该能够前后移动。转发将突出显示并阅读下一个句子,后退则相反。就是这样一个软件的例子。我的程序每次按播放按钮只能读一句文字,但无法继续。
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;
}