博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF制作的一个小功能,智能提示(IntelliSense)
阅读量:5278 次
发布时间:2019-06-14

本文共 2734 字,大约阅读时间需要 9 分钟。

原文

最近WPF项目中遇到一个需求,需要给一个RichTextBox添加智能提示(IntelliSense)功能。

分析下具体的需求,在用户键入"@"符号时,应该显示一个弹出框,把所有用户列出。用户可以通过键盘、鼠标等进行选择。用户列表可能数据比较多,那么用户还应该可以输入字符进行筛选。用过各种IDE开发工具的童鞋应该对这样的效果很了解了,具体效果如下

输入@符号的效果:

筛选的效果:

再谈谈具体的开发思路.

1.如何制作可以实现列表选择功能的弹出框

  方法很多,Popup+ListBox可以完美解决.此处我为了省代码,直接用的ListBox

2.如何在键入@符号时,将ListBox显示在@符号之后

  在VisualStudio的智能提示里,当我们触发了IntelliSense时,提示框会显示,并且与下一字符的插入点对齐。TextPointer类提供了方法可以获取到某个插入点的坐标:

1     RichTextBox textbox = this.RichTextBox;2     TextPointer start = textbox.Selection.Start;3     Rect rect = start.GetCharacterRect(LogicalDirection.Forward);4     Point point = rect.BottomLeft;

  我们可以注册RichTextBox的键盘事件,判断用户是否键入@符号。@符号是由“Shift”+“2”组成,Keyboard.Modifiers可以获取到组合键:

1 if (Keyboard.Modifiers == ModifierKeys.Shift && e.Key == Key.D2)2 {3     //TODO: 用户键入了@符号4 }

  在TODO里,将ListBox移动到得到Point位置即可。

3.如何实现选择和筛选

  筛选功能很简单,保存一个局部变量,在智能提示框显示后记录用户输入,智能提示框隐藏后清空,智能提示框中的数据按照该变量进行过滤即可。

  当智能提示框显示的时候,用户是可以键入“上”,“下”键进行移动选择的。也许在敲了几次方向键,用户还想继续输入字符进行筛选。最开始,我是 用的ListBox自动的选择功能,当用户敲入方向键,我就将键盘焦点(WPF中分键盘焦点和逻辑焦点,这个也是困扰我很久的问题)设置到ListBox 上,那么用户就可以敲入“上”,“下”键进行移动选择了。看起来很简单,但是这样是有问题的,因为用户如果想继续敲入字符筛选,我还必须将键盘焦点重新设 置到RichTextBox上,否则用户的敲击是无效的。

  后来突然想通了,在用户敲击“上”,“下”键时,只需要调用ListBox的MoveCurrentToPrevious()和 MoveCurrentToNext()即可,这样给用户的错觉还是有了上下移动的效果。焦点不在ListBox上时,这样的移动可能造成当前选中项超出 了显示范围之外,那么可以通过ListBox的ScrollIntoView()方法,将选中对象滚动到视图中。

  下面是截取的一段代码:

1           //如果按了向下键,则把选中项下移 2                 if (e.Key == Key.Down) 3                 { 4                     if (UserList.CurrentPosition != UserList.Count - 1) 5                     { 6                         lbUser.Items.MoveCurrentToNext(); 7                         lbUser.ScrollIntoView(lbUser.Items.CurrentItem); 8                     } 9                     e.Handled = true;10                 }11                 //如果按了向上键,则把选中项上移12                 if (e.Key == Key.Up)13                 {14                     if (UserList.CurrentPosition != 0)15                     {16                         lbUser.Items.MoveCurrentToPrevious();17                         lbUser.ScrollIntoView(lbUser.Items.CurrentItem);18                     }19                     e.Handled = true;20                 }

4.实现选中和取消

  选中功能就更简单了,分别加入对鼠标双击,空格,回车,TAB等的判断,将ListBox的当前选中项的文本插入到 RichTextBox中即可。需要注意的是,此处要对单击做判定,由于单击ListBox会使键盘焦点设置到其之上,因此要强制将键盘焦点从 ListBox移开。判断ESC键,使ListBox隐藏即可实现取消功能。

5.如何实现扩展

  做一个功能最重要的就是考虑以后的重用,此处可以公开 KeyBoard.Modifyers,KeyCode,IEnumable<T>为依赖属性,前2个代表在敲入什么组合键时会弹出智能提示 框,最后一个是弹出内容的数据源。由于此处的筛选功能是在控件内部,那么我们可以定义一个接口,包含一个Name属性。 

1 public interface IData2 {3     //用于筛选和插入的名称4     string Name { get; set; }5 }

  将上面的IEnumable<T>改为IEnumable<IData>。

  以后的调用方,只需要将这3个中的一个或多个传入,即可实现智能提示功能。

posted on
2013-07-25 08:39 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/3213592.html

你可能感兴趣的文章
《软件测试》--第四次博客作业
查看>>
git基本使用
查看>>
开篇寄语
查看>>
ES6特性的两点分析
查看>>
Java注解
查看>>
如何在CSS中使用变量
查看>>
软件测试工作量的评估清单
查看>>
Object C学习笔记8-字符串NSString之二
查看>>
算法笔记 3.2 codeup1935 查找学生信息
查看>>
DataTable转List,转对象
查看>>
1185: 零起点学算法92——单词数
查看>>
IOS HTML点击时有背景阴影
查看>>
svn登录问题
查看>>
[Java复习01] Java基础 Basic
查看>>
使用scipy.genfromtxt()报错
查看>>
java-接口—策略模式
查看>>
[AHOI2006]文本编辑器 Splay tree区间操作
查看>>
android自定义动画
查看>>
ANR和FC
查看>>
bzoj 2823: [AHOI2012]信号塔 最小圆覆盖
查看>>