首先要做的事情就是定义一个popup来显示我们需要展示的东西

<Popup x:Name="ConfigPopup" Height="auto" Width="" StaysOpen="False" Placement="Bottom" IsOpen="False" HorizontalAlignment="Left">
<Grid Width="auto" Height="auto">
<ListBox x:Name="MailConfigSelection" KeyDown="MailConfigSelection_OnKeyDown" IsTextSearchEnabled="True" ItemsSource="{Binding KeysCollection}"></ListBox>
</Grid>
</Popup>

  这里使用的是用一个Listbox来做演示,也可以使用其他的控件或者改listbox的template。popup的staysopen代表失去焦点后还显不显示。listbox绑定到一个ObservableCollection来实时改变。

  后台代码

public ObservableCollection<string> KeysCollection { get; set; } = new ObservableCollection<string>(); 

...

private void MailConfigSelection_OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
ConfigPopup.IsOpen = false;
System.Windows.Controls.ListBox lb = sender as System.Windows.Controls.ListBox;
if (lb == null) return; string mailConfig = lb.SelectedItem.ToString(); //Popup pp = (lb.Parent as Grid).Parent as Popup;
TextBox tb = ConfigPopup.PlacementTarget as TextBox;
int i = tb.CaretIndex;//获取呼出这个popup的textbox的当前光标位置
tb.Text = tb.Text.Insert(i, mailConfig) + ">";//插入选择的字符串
tb.CaretIndex = i + mailConfig.Length + ;//移动光标
tb.Focus();
}
else if (e.Key == Key.Escape)
{
ConfigPopup.IsOpen = false;
}
}

  给textbox加上keyup响应事件

private void TextBox_OnKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key != Key.OemComma) return; TextBox tbm = e.OriginalSource as TextBox;
if (tbm.Text.EndsWith("<") && KeysCollection.Count != )//这里是这样的条件,可以根据需求来改变
{
ShowPopUp(tbm.GetRectFromCharacterIndex(tbm.CaretIndex), tbm);
}
}

  弹出popup时,我们希望popup出现在正在输入的textbox下面而且在输入的光标附近

private void ShowPopUp(Rect placementRect, TextBox tb)
{
ConfigPopup.PlacementTarget = tb;
ConfigPopup.PlacementRectangle = placementRect;
ConfigPopup.IsOpen = true;
MailConfigSelection.Focus();
MailConfigSelection.SelectedIndex = ;
var listBoxItem = (ListBoxItem)MailConfigSelection.ItemContainerGenerator.ContainerFromItem(MailConfigSelection.SelectedItem);
listBoxItem.Focus();
}

  我们先获取到当前光标的位置Rect,tbm.GetRectFromCharacterIndex(tbm.CaretIndex)来获取rect并传给popup的PlacementRectangle,这样popup出现的位置就是我们想要的了。

  在这个过程中发现弹出窗口后选择候选项时,按上下键有时候不管用,因为我们focus在popup上,上下键相应的框内所有内容的上下翻,我们希望的是在各个选项之间的切换,那么我们需要focus在里面的listitem上,通过MailConfigSelection.ItemContainerGenerator.ContainerFromItem(MailConfigSelection.SelectedItem)来获取到选中的listboxitem并把焦点给他即可。

  到此,一个类智能感知就完成了,可以通过其他的各种方式来进行优化。

WPF中实现类智能感知的更多相关文章

  1. Visual Studio中Js使用智能感知

    使用了第三方的JS库或框架,在VS中编写JS代码,发现真是个悲剧,完全只能手打,智能感知没了,这不符合VS的一贯做风只要在写代码的JS文件加上以下代码,就可以有智能感知了 ///<referen ...

  2. tsd-提升IDE对JavaScript智能感知的能力

    在编写前端JavaScript代码时,最痛苦的莫过于代码的智能感知(Intelli Sense). 追其根源,是因为JavaScript是一门弱类型的动态语言.对于弱类型的动态语言来说,智能感知就是I ...

  3. Visual Studio中你所不知道的智能感知

    在Visual Studio中的智能感知,相信大家都用过.summary,param,returns这几个相信很多人都用过的吧.那么field,value等等这些呢. 首先在Visual Studio ...

  4. WPF中Image控件绑定到自定义类属性

    首先我们定义一个Student类,有ID,Name,Photo(保存图片路径). using System; using System.Collections.Generic; using Syste ...

  5. WPF中查找控件的扩展类

    在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便. 贴出来,供大家参考. /// <summa ...

  6. WPF中的3D特性和常见的几个类

    原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1.  Visual 类      所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...

  7. WPF中的Application类。

    原文:WPF中的Application类. Application对象用的名称空间是system.windows 1.手动创建Application对象步骤. 1.1).把项目中的App.Xaml文件 ...

  8. WPF中Timer与DispatcherTimer类的区别

    前几天在WPF中写了一个轨迹回放的功能,我想稍微做过类似项目的,都晓得采用一个时间控件或者时间对象作为调度器,我在这么做的时候,出现了问题,于是将程序中的Timer换成了DispatchTimer,然 ...

  9. (转载)WPF中的动画——(一)基本概念

    http://www.cnblogs.com/TianFang/p/4050845.html WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面.首先,我们来复习一下动画的基本概念.计 ...

随机推荐

  1. 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开

    [kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...

  2. 玩玩kafka1 单机安装

    今天主要来一遍kafka单机版的安装,比较简单易上手,关于kafka的介绍我就不贴了,大家可以自行搜索 1.首先将tgz包传到centos目录下(这里使用xftp工具) ok后查看一下tgz包是否已经 ...

  3. TreeSet小练习

    package 练习.test1; import java.util.Iterator; import java.util.TreeSet; /* 需求:将字符串中的数值进行排序. 例如String ...

  4. 用Docker在一台笔记本电脑上搭建一个具有10个节点7种角色的Hadoop集群(上)-快速上手Docker

    如果想在一台电脑上搭建一个多节点的Hadoop集群,传统的方式是使用多个虚拟机.但这种方式占用的资源比较多,一台笔记本能同时运行的虚拟机的数量是很有限的.这个时候我们可以使用Docker.Docker ...

  5. pod lib lint 遇到的问题

    在pod lib lint(Xcode 8.3.2)校验组件是否有效的时候报了如下错误: - ERROR | [iOS] unknown: Encountered an unknown error ( ...

  6. GreenDao

    前言 我相信,在平时的开发过程中,大家一定会或多或少地接触到 SQLite.然而在使用它时,我们往往需要做许多额外的工作,像编写 SQL 语句与解析查询结果等.所以,适用于 Android 的ORM ...

  7. Git分支合并选择

    用Git进行多人协作开发时,必然会合并代码,解决冲突.然而合并代码也是需要点技巧的,如果对一些关键命令没有理解去使用的话,git的版本演进路线就会变得很乱,从而造成了日后维护的一些麻烦. Git上合并 ...

  8. WINFORM实现进程信息的查看,listview,点击,右键,右键菜单

    1.   程序设计要求 设计程序来获取计算机中的进程信息 2.程序设计流程图 3.程序设计亮点 (0)程序启动时加载guide引导使用视频 (1)使用Listview控件显示出所有控件的名称. (2) ...

  9. 5、Java Swing布局管理器(FlowLayout、BorderLayout、CardLayout、BoxLayout、GirdBagLayout 和 GirdLayout)

    5.Java-Swing常用布局管理器       应用布局管理器都属于相对布局,各组件位置可随界面大小而相应改变,不变的只是其相对位置,布局管理器比较难以控制,一般只在界面大小需要改是才用,但即使这 ...

  10. Struts2 Handle 404 error page and wrong action

    1. To handle 404 not found yourself, just add this code to your web.xml <error-page> <error ...