文章目录
- 绑定快捷键
- 翻页功能
- 跳转到首尾
- 章节跳转
txt阅读器系列:
- 需求分析和文件读写
- 目录提取类💎列表控件与目录
- 字体控件绑定💎前景/背景颜色
- 书籍管理系统💎用树形图管理书籍
- 语音播放💎播放进度显示💎快进快退💎语速音量
绑定快捷键
目前来说,这个txt阅读器只能一行一行滚动着看,但看小说往往是一页一页看,所以接下来就要实现翻页功能,而具体的实现细节,除了要有按钮控制之外,最好还能够用快捷键来控制。
注册快捷键的方式非常简单,只需添加一个PreviewKeyDown
委托即可,含义是,当按下键盘时触发。
PreviewKeyDown += MainWindow_PreviewKeyDown;
然后具体的快捷键逻辑,这里希望用PageDown
和PageUp
这两个按键来实现翻页功能,分别是向前和向后翻页。这两个功能其实在TextBox
中已经实现了,那么现在创建的全局快捷键,则无需让光标聚焦到TextBox
内部,即可相应。
其C#
代码如下。
private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
int n = 0;
switch (e.Key)
{
case Key.PageDown: n=1; break;
case Key.PageUp: n=-1; break;
}
switch (e.KeyboardDevice.Modifiers)
{
case ModifierKeys.None: turnPage(n);break;
}
}
而MainWindow_PreviewKeyDown代码中,除了考虑到PageDown和PageUp这两个按键之外,还考虑到了是否按下了其他功能键,其中ModifierKeys为一个枚举类型,包含None, Alt, Control, Shift, Windows共5个选项。
翻页功能
翻页函数为turnPage
,代码如下
private void turnPage(int n)
{
int st = txt.GetFirstVisibleLineIndex();
int ed = txt.GetLastVisibleLineIndex();
st +=(ed - st) * n;
st = Math.Max(st, 0);
st = Math.Min(txt.LineCount - (ed-st), st);
st = Math.Min(txt.LineCount, st);
txt.ScrollToLine(st);
}
其中,n
为1时表示向后翻页;-1表示向前翻页。st和ed分别为当前TextBox中所显示的文字的首尾行号,最后ScrollToLine表示滚动条滑动到指定行所在位置。
跳转到首尾
除了翻页之外,有的时候还有跳转到开头或者结尾的功能,尤其跳转到开头,在阅读的时候还是比较常见的。为此,可以注册Home
和End
这两个快捷键
switch (e.Key)
{
case Key.PageDown: n=1; break;
case Key.PageUp: n=-1; break;
case Key.Home: n=-10000; break;
case Key.End: n=10000; break;
}
由于在turnPage
这个函数中,会对最大值最小值做出保护,所以这里只是给n
赋了一个很大的值10000。最终效果如下
考虑到有些电脑没有PageDown, PageUp
等按键,也可以为其再添加一些额外的快捷键,其按键选择代码可以改为
switch (e.Key)
{
case Key.PageDown:
case Key.N : n=1; break;
case Key.PageUp:
case Key.L: n=-1; break;
case Key.Home:
case Key.H: n=-10000; break;
case Key.End:
case Key.E: n=10000; break;
}
章节跳转
除了翻页之外,章节跳转也是比较常见的功能。由于前面已经将目录和ListBox
绑定在了一起,而ListBox
在发生变更时已经注册了事件。所以可直接修改ListBox
当前选定的子项,便可以完成目录跳转。
具体实现代码为
private void turnTitle(int n)
{
int ind = lvCatalog.SelectedIndex + n;
ind = Math.Max(ind, 0);
ind = Math.Min(ind, lvCatalog.Items.Count - 1);
lvCatalog.SelectedIndex = ind;
}
其调用条件为
switch (e.KeyboardDevice.Modifiers)
{
case ModifierKeys.Control: turnTitle(n); break;
}