博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
增加智能感知的RichTextBox扩展控件(WPF)
阅读量:6828 次
发布时间:2019-06-26

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

 

简介

 

闲来无事,写篇博客打发时间。前几日想给WPF的RichTextBox新增上智能感知的功能,搜了一圈没有找到合适的开源代码,于是自己花了点时间搞定了它,小小的扩展了一下RichTextBox,先看效果图:

intellisense_rich_text_box.png

怎么使用这个扩展后的RichTextBox

扩展后的RTB新增了几个依赖属性:

ContentAssistSource:智能感知数据源

ContentAssistTriggers:智能感知触发器(即当输入哪些字符时会显示智能感知)

AutoAddWhiteSpaceAfterTriggered:当选择提示中的某一项时,是否自动增加空格

可以直接在xaml中这样使用:

<rabbit:RichTextBoxEx Name="richTextBoxEx1"

AutoAddWhiteSpaceAfterTriggered="{Binding IsChecked,ElementName=chkAutoAddWhitespace}"
ContentAssistTriggers
="{Binding ContentAssistTriggers}"
ContentAssistSource
="{Binding ContentAssistSource}" />

很简单吧?

如何实现的?

一、准备

为了实现这一功能,我首先在扩展后的rtb中添加一个ListBox,作为智能提示数据源的载体。在rtb 加载后将ListBox添加到它的父容器中(为了方便控制位置,此处强制父容器为Grid),如下代码片断:

 
private
 ListBox AssistListBox 
=
 
new
 ListBox();
void
 RichTextBoxEx_Loaded(
object
 sender, RoutedEventArgs e)
           {
               
//
init the assist list box
               
if
 (
this
.Parent.GetType() 
!=
 
typeof
(Grid))
               {
                   
throw
 
new
 Exception(
"
this control must be put in Grid control
"
);
               }
               
if
 (ContentAssistTriggers.Count 
==
 
0
)
               {
                   ContentAssistTriggers.Add(
'
@
'
);
               }
               (
this
.Parent 
as
 Grid).Children.Add(AssistListBox);
               AssistListBox.MaxHeight 
=
 
100
;
               AssistListBox.MinWidth 
=
 
100
;
               AssistListBox.HorizontalAlignment 
=
 System.Windows.HorizontalAlignment.Left;
               AssistListBox.VerticalAlignment 
=
 System.Windows.VerticalAlignment.Top;
               AssistListBox.Visibility 
=
 System.Windows.Visibility.Collapsed;
               AssistListBox.MouseDoubleClick 
+=
 
new
 MouseButtonEventHandler(AssistListBox_MouseDoubleClick);
               AssistListBox.PreviewKeyDown 
+=
 
new
 KeyEventHandler(AssistListBox_PreviewKeyDown);
           }

 

你看到了,我给ListBox新增了MouseDoubleClick 和PreviewKeyDown 事件,就是为了方便用户选择提示的内容。事件中都做了哪些事件呢?就是简单的将当前选中的Item的值插入到RichTextbox中。在此不贴代码了。

二、如何显示

做完准备工作后,如何在用户输入某些特定的字母后,出现对应的提示呢?

其实也挺简单,重写一下OnTextInput事件,在该事件里做一些判断,如果满足出现提示的条件,就把ListBox给显示到合适的位置,同时再做一些其他的工作,就ok了:

protected override void OnTextInput(System.Windows.Input.TextCompositionEventArgs e)

           {
               base.OnTextInput(e);
               
if (IsAssistKeyPressed == false && e.Text.Length == 1)
               {
                   
if (ContentAssistTriggers.Contains(char.Parse(e.Text)))
                   {
                       ResetAssistListBoxLocation();
                       IsAssistKeyPressed 
= true;
                       FilterAssistBoxItemsSource();
                       
return;
                   }
               }
               
if (IsAssistKeyPressed)
               {
                   sbLastWords.Append(e.Text);
                   FilterAssistBoxItemsSource();
               }
           }

接下来再override一个OnPreviewKeyDown事件,处理一下用户的按键事件,比如当用户按下enter或tab时,就表明用户想选择当前的第一项,当按下Down键时,意味着用户想选择下一项等等,如下代码所示:

 
protected
 
override
 
void
 OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e)
           {
               
if
 (
!
IsAssistKeyPressed)
               {
                   
base
.OnPreviewKeyDown(e);
                   
return
;
               }
               ResetAssistListBoxLocation();
               
if
 (e.Key 
==
 System.Windows.Input.Key.Back)
               {
                   
if
 (sbLastWords.Length 
>
 
0
)
                   {
                       sbLastWords.Remove(sbLastWords.Length 
-
 
1
1
);
                       FilterAssistBoxItemsSource();
                   }
                   
else
                   {
                       IsAssistKeyPressed 
=
 
false
;
                       sbLastWords.Clear();
                       AssistListBox.Visibility 
=
 System.Windows.Visibility.Collapsed;
                   }
               }
               
//
enter key pressed, insert the first item to richtextbox
               
if
 ((e.Key 
==
 Key.Enter 
||
 e.Key 
==
 Key.Space 
||
 e.Key 
==
 Key.Tab))
               {
                   AssistListBox.SelectedIndex 
=
 
0
;
                   
if
 (InsertAssistWord())
                   {
                       e.Handled 
=
 
true
;
                   }
               }
               
if
 (e.Key 
==
 Key.Down)
               {
                   AssistListBox.Focus();
               }
               
base
.OnPreviewKeyDown(e);
           }

到现在为止,扩展的richtextbox已经具备了智能感知的功能。上面的几个代码块中都用到了一个方法,FilterAssistBoxItemsSource(),它是负责ListBox的显示或是隐藏的:

 

private
 
void
 FilterAssistBoxItemsSource()
           {
               IEnumerable
<
string
>
 temp 
=
 ContentAssistSource.Where(s 
=>
 s.ToUpper().StartsWith(sbLastWords.ToString().ToUpper()));
               AssistListBox.ItemsSource 
=
 temp;
               AssistListBox.SelectedIndex 
=
 
0
;
               
if
 (temp.Count() 
==
 
0
)
               {
                   AssistListBox.Visibility 
=
 System.Windows.Visibility.Collapsed;
               }
               
else
               {
                   AssistListBox.Visibility 
=
 System.Windows.Visibility.Visible;
               }
           }

 

有感兴趣的,就下载下来演示看看。感觉到对自己的项目有用的,就下下来源码看看。如果觉得不符合自己的需求,就改改。
 

转载地址:http://bbjkl.baihongyu.com/

你可能感兴趣的文章
RHEL6基础二十七之quota磁盘配额管理
查看>>
Bundle 小镇中由 EasyUI 引发的“血案”
查看>>
USB启动盘制作详解 (一) ISOTOUSB软件
查看>>
MongoDB 计划缓存的影响
查看>>
让linux服务器支持https(安全http协议)
查看>>
Django 笔记 模型数据的读取
查看>>
02-Windows Server 2012 新特性 ---- 管理中心
查看>>
PowerShell 远程连接指定 TrustedHost
查看>>
SQL Server 2014 内存优化表(1)实现内存优化表
查看>>
PowerShell Script Analyzer, Script browser 和 Pester
查看>>
Exchange 日常管理之一:用户邮箱完全访问权限
查看>>
kickstart+pxe 实现无人值守自动安装
查看>>
Exchange server 2013(十四)WSUS部署及组策略设置(2)
查看>>
SCCM2012系列之一,SCCM2012之初步印象
查看>>
JavaScript(React Native、Node.js等)移动、服务端通吃的全栈语言
查看>>
你了解这么多万兆以太网规范吗?
查看>>
Java向前引用容易出错的地方
查看>>
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(1)...
查看>>
部署无需边缘提供外部访问的Lync Server前端
查看>>
最常用的四种数据分析方法
查看>>