首先要做的事情就是定义一个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. dva框架使用mock.js模拟数据 + fetch请求数据

    what DVA? Dva是基于Redux做了一层封装,对于React的state管理,有很多方案,我选择了轻量.简单的Dva. dva 可以很方便就使用mock.js进行数据的模拟. 只需要三步,即 ...

  2. 【2017-05-03】winform打印控件、事件对象和事件数据、MDI窗体容器

    一.打印控件 第一步先把打印对象搞出来. - printDocument    打印对象(将要打印的内容放到该对象里,从该对象里取内容打印) 设置他的PrintPage事件(对于要打印的每一页触发一次 ...

  3. Docker - 定制镜像

    Dockerfile Docker Hub拥有大量高质的官方镜像:可直接使用的服务类镜像.语言应用镜像.基础操作系统镜像等,满足绝大部分需求. 此外,可以通过定制镜像的方式来满足实际使用中的特定需求. ...

  4. “永恒之蓝"漏洞的紧急应对--毕业生必看

    早上6点多起床了,第一次起这么早,昨天晚上12点多,看到了一则紧急通知,勒索软件通过微软"永恒之蓝"漏洞针对教育网进行了大规模的攻击,而且有很多同学中招.中招后的结果如下图所示. ...

  5. Vmware虚拟机中安装cnetOS7详细图解步骤

    1.安装VMware 下载一个软件安装: .新建一个虚拟机 .引用安装包 4.启动新建的虚拟机 .安装CentOS7的步骤 配置系统语言: 配置系统时间: 配置系统键盘: 配置键盘切换的快捷键: 配置 ...

  6. 反序列py脚本分享(原创)

    代码如下: #!/usr/bin/env python # coding=utf-8 import socket import sys import requests import base64 im ...

  7. Java学习笔记——浅谈数据结构与Java集合框架(第三篇、Map)

    桃李春风一杯酒,江湖夜雨十年灯 --寄黄几复 之前图上写错了,是Hashtable类.t是小写的,它是个很古老的类,以至于命名都没有那么规范.. HashMap HashMap就是存储key-valu ...

  8. GROUP BY语句与HAVING语句的使用

    一.GROUP BY GROUP BY语句用来与聚合函数(aggregate functions such as COUNT, SUM, AVG, MIN, or MAX.)联合使用来得到一个或多个列 ...

  9. STM32采集电阻触摸贴膜

    今天为了解决一个测量电阻屏压力的问题,自己直接用STM32做了一个测量电阻屏的程序(直接把触摸屏的四根线接到单片机引脚上),通过AD切换采集,采集X轴电压,Y轴电压,和压力..最后附上自己的程序 先说 ...

  10. CountDownLatch——闭锁的实现之一

    CountDownLatch实际上是一种闭锁实现.闭锁:是一种同步工具类,可以延迟线程的进度知道其到达终止状态--<Java并发编程实战>.这个怎么解释呢?简单来说,就是有1个线程需要等待 ...