文章目录
- 播放进度
- 光标跟踪
- 进度条
txt阅读器系列:
- 需求分析和文件读写
- 目录提取类💎列表控件与目录
- 字体控件绑定💎前景/背景颜色
- 书籍管理系统💎用树形图管理书籍
- 语音播放
播放进度
SpeechSynthesizer对象可以注册Speech_SpeakProgress事件,当被触发时,可以返回当前的阅读进度,每次新建speech之后,可以绑定。下面稍做测试
private void txtChange(string text)
{
txt.Text = text;
speech = new SpeechSynthesizer();
speech.SpeakProgress += Speech_SpeakProgress;
}
private void Speech_SpeakProgress(object? sender, SpeakProgressEventArgs e)
{
Dispatcher.Invoke(() => {
txtInfo.Text = $"{e.Text}, {e.CharacterPosition}, {e.AudioPosition}"; });
}
由于需要调用窗口对象,所以用到了Dispatcher.Invoke函数。
其中,e.Text表示当前朗读的单词;e.CharacterPosition表示当前朗读字符所在位置;e.AudioPosition表示当前播放时间,其效果如下

光标跟踪
既然能够反馈文本位置,就可以设置更多的功能,比如快速定位当前阅读位置,将Speech_SpeakProgress内容改为
private void Speech_SpeakProgress(object? sender, SpeakProgressEventArgs e)
{
Dispatcher.Invoke(() => {
txt.CaretIndex = e.CharacterPosition;
txt.SelectionStart = e.CharacterPosition;
txt.SelectionLength = e.Text.Length;});
}
其中,CaretIndex用于控制滚动条随着光标移动;txt.SelectionStart控制被选中文本的起始点;Txt.SelectionLength表示选中文本的长度。
但仅仅是这样还不够,尽管我们选中了文本,但txt控件并不是窗口的焦点,所以窗口会认为我们没在关注txt,所以并不会展示选区的变化。所以,在speechTask运行前后,需要添加一行txt.Focus,从而结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-17V3tIE9-1685763546165)(csharp/wpf_txt_12.gif)]
进度条
如果觉得文字的表现力不够,还可以再加一个进度条,其xaml代码写在txt前面,内容如下
<ProgressBar DockPanel.Dock="Bottom" x:Name="pgBarText" Height="2"/>
然后在Speech_SpeakProgress的Dispatcher中添加进度条调控的代码,修改之后内容如下
private void Speech_SpeakProgress(object? sender, SpeakProgressEventArgs e)
{
Dispatcher.Invoke(() => {
txt.CaretIndex = e.CharacterPosition;
txt.SelectionStart = e.CharacterPosition;
txt.SelectionLength = e.Text.Length;
pgBarText.Value = 100.0 * e.CharacterPosition / txt.Text.Length;
});
}
其中新添加的这行就用于调控进度条,进度条最大值为100,所以用100.0乘上当前阅读的进度。



















