一个自动完成插件的类(TextBox 版)
弄着玩.还蛮有意思的..应该还有很多BUG跟用起来不舒服的地方吧..希望路过的朋友给提下意见.谢谢...
/// <summary>
/// for TextBox
/// </summary>
public class IMYansSuggest<TEntity> where TEntity : class
{
#region events
public delegate void OnConfirmHandler(TEntity entity);
public event OnConfirmHandler OnConfirm;
#endregion
#region private controls
TextBox iwin;
Panel panel;
DataGridView dgv;
#endregion
List<TEntity> lstData;
public IMYansSuggest(TextBox IWin) {
iwin = IWin;
bindWin();
}
public IMYansSuggest(TextBox IWin, List<TEntity> lstdata) {
iwin = IWin;
lstData = lstdata;
bindWin();
InitializeComponent();
}
/// <summary>
/// 设置数据源
/// </summary>
/// <param name="lstdata"></param>
public void SetCustomDataSource(List<TEntity> lstdata) {
lstData = lstdata;
InitializeComponent();
}
List<string> showColumns = new List<string>();
/// <summary>
/// 设置显示字段
/// </summary>
/// <param name="column">显示字段</param>
public void SetShowColumns(params string[] column) {
showColumns = column.ToList();
}
/// <summary>
/// 获取显示字段
/// </summary>
/// <returns></returns>
public List<string> GetShowColumns() {
if (showColumns.Count > 0)
return showColumns;
return typeof(TEntity).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).Select(Y => Y.Name).ToList();
}
string enterColumn = string.Empty;
/// <summary>
/// 设置填入文本信息
/// </summary>
/// <param name="columnName"></param>
public void SetEnterColumnName(string columnName) {
enterColumn = columnName;
}
void InitializeComponent() {
if (null == dgv) {
dgv = new DataGridView();
dgv.AutoGenerateColumns = false;
panel = new Panel();
panel.Controls.Add(dgv);
dgv.Dock = DockStyle.Fill;
panel.Visible = false;
iwin.Parent.Controls.Add(panel);
panel.Top = iwin.Top + iwin.Height;
panel.Left = iwin.Left;
foreach (var v in GetShowColumns()) {
var dc = new DataGridViewTextBoxColumn();
dc.DataPropertyName = v;
dc.Name = v;
dgv.Columns.Add(dc);
}
dgv.DataSource = lstData;
panel.BringToFront();
dgv.RowHeadersVisible = false;
dgv.RowTemplate.Height = 18;
dgv.ColumnHeadersVisible = false;
dgv.AllowUserToDeleteRows = false;
dgv.AllowUserToAddRows = false;
dgv.AllowUserToResizeColumns = false;
dgv.AllowUserToResizeRows = false;
dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgv.MultiSelect = false;
dgv.TabStop = false;
panel.HorizontalScroll.Enabled = false;
panel.Width = dgv.Columns.Cast<DataGridViewColumn>().Sum(Y => Y.Width) + 20;
dgv.LostFocus += new EventHandler(IWin_LostFocus);
dgv.CellDoubleClick += new DataGridViewCellEventHandler(dgv_CellDoubleClick);
}
}
void dgv_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
if (e.RowIndex > -1) {
SetIWinValue((TEntity)dgv.CurrentRow.DataBoundItem);
iwin.SelectAll();
}
}
void bindWin() {
iwin.TextChanged += new EventHandler(IWin_TextChanged);
iwin.LostFocus += new EventHandler(IWin_LostFocus);
iwin.GotFocus += new EventHandler(iwin_GotFocus);
iwin.MouseWheel += new MouseEventHandler(iwin_MouseWheel);
iwin.KeyDown += new KeyEventHandler(iwin_KeyDown);
}
void iwin_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Up) {
scrollUp();
}
else if (e.KeyCode == Keys.Down) {
scrollDown();
}
else if (e.KeyCode == Keys.Enter) {
if (null != dgv.CurrentRow) {
SetIWinValue((TEntity)dgv.CurrentRow.DataBoundItem);
}
}
}
public string GetShowColumn() {
if (enterColumn.Length > 0)
return enterColumn;
return typeof(TEntity).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)[0].Name;
}
void SetIWinValue(TEntity entity) {
if (null != OnConfirm) {
OnConfirm(entity);
}
else {
iwin.Text = typeof(TEntity).GetProperty(GetShowColumn()).GetValue(entity, null).ToString();
}
}
/// <summary>
/// 鼠标滚动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void iwin_MouseWheel(object sender, MouseEventArgs e) {
if (e.Delta > 0) {
scrollUp();
}
else if (e.Delta < 0) {
scrollDown();
}
}
/// <summary>
/// 获得焦点
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void iwin_GotFocus(object sender, EventArgs e) {
if (null != dgv) {
panel.Visible = true;
}
iwin.SelectAll();
}
/// <summary>
/// 失去焦点
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IWin_LostFocus(object sender, EventArgs e) {
if (null != dgv && dgv.Visible && !dgv.Focused && !iwin.Focused) {
panel.Visible = false;
}
}
void scrollUp() {
if (null == dgv.CurrentRow) {
dgv.ClearSelection();
dgv.Rows[0].Selected = true;
dgv.CurrentCell = dgv.Rows[0].Cells[0];
}
else {
var index = dgv.SelectedRows[0].Index;
if (index > 0) {
dgv.ClearSelection();
dgv.Rows[index - 1].Selected = true;
dgv.CurrentCell = dgv.Rows[index - 1].Cells[0];
}
}
}
void scrollDown() {
if (null == dgv.CurrentRow) {
dgv.ClearSelection();
dgv.Rows[0].Selected = true;
dgv.CurrentCell = dgv.Rows[0].Cells[0];
}
else {
var index = dgv.SelectedRows[0].Index;
if (index != dgv.Rows.Count - 1) {
dgv.ClearSelection();
dgv.Rows[index + 1].Selected = true;
dgv.CurrentCell = dgv.Rows[index + 1].Cells[0];
}
}
}
/// <summary>
/// 文本改变
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IWin_TextChanged(object sender, EventArgs e) {
bool isFinded = false;
for (int i = 0; i < dgv.Rows.Count; i++) {
var row = dgv.Rows[i];
// foreach (DataColumn dc in data.Columns) {
foreach (var v in GetShowColumns()) {
if (row.Cells[v].Value.ToString().StartsWith(iwin.Text, true, System.Globalization.CultureInfo.InvariantCulture)) {
dgv.ClearSelection();
row.Selected = true;
dgv.CurrentCell = row.Cells[0];
isFinded = true;
break;
}
}
if (isFinded) break;
}
}
}
实例化一个类出来,,请指明所用数据源的类型,,再指定一个数据源即可...
实例如下:
{
public frmMain() {
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e) {
var lstPerson = new List<Person>();
Random r = new Random();
for (int i = 1; i < 100; i++) {
lstPerson.Add(new Person {
ID = i,
Name = "yans" + i.ToString(),
Age = r.Next(1, 100),
Remark = "this just a remark for you."
});
}
new IMYansSuggest<Person>(textBox1, lstPerson);
}
}
class Person
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Remark { get; set; }
}
效果图:
当然你可以自己设置要填充文本框的属性名或者是设置要显示的属性..
转载于:https://www.cnblogs.com/yans/archive/2011/01/05/1926458.html
一个自动完成插件的类(TextBox 版)相关推荐
- 手机自动化测试工具Auto.js学习使用(附一个自动刷抖音类短视频的demo)
Auto.js学习使用 介绍 使用 1. 手机端安装auto.js 2.电脑下载vscode,安装插件 3.手机打开远程开发功能 4. vscode连接手机 5.进行开发(一个自动刷抖音类短视频的de ...
- 最新WordPress系统文章自动采集插件Auto Post完美运行版
源码介绍: 今天有用户咨询wp的采集插件,找了一个WordPress文章采集插件Auto Post Pro3.6.2版本,可以多线程采集.自动采集免授权学习版,目前完美运行于的WordPress各个版 ...
- Dreamweaver Cs4 jQuery自动提示插件绿色版
最近在学jQuery,想弄一个快速的开发工具,找出尘封已久的精简版的Dreamweaver cs4,安装包总共才76.5M,一分钟不到就安完了,相比完整版臃肿的身躯,像我这种只用其中小部分功能的人来说 ...
- 一个CSS的px值转rem值的Sublime Text 3自动完成插件
一个CSS的px值转rem值的Sublime Text 3自动完成插件. 插件效果如下: 安装 下载本项目,比如:git clone https://github.com/flashlizi/cssr ...
- C++插件管理类(下)——实际项目(阉割版)
文章目录 一.背景 二.代码结构 三.两个CMakeLists.txt 3.1 父目录 3.2 子目录src 四.代码实例 4.1 main.cpp 4.2 Plugin.h 4.3 Plugin.c ...
- 2019年写一个Cloud Studio插件吧
纳尼?2019年?其实一开始我的内心是拒绝的,一转眼就到了2018年的尾声,再不写个[2019年]的标题定好文章的保质期,感觉刚写这篇文章就要过期了!然而,回顾2018年,每每想起2018年的收获,我 ...
- 2019年如何撸一个Cloud Studio插件?
纳尼?2019年?其实一开始我的内心是拒绝的,一转眼就到了2018年的尾声,再不写个[2019年]的标题定好文章的保质期,感觉刚写这篇文章就要过期了!然而,回顾2018年,每每想起2018年的收获,我 ...
- 【深入浅出MyBatis系列八】SQL自动生成插件
为什么80%的码农都做不了架构师?>>> #0 系列目录# 深入浅出MyBatis系列 [深入浅出MyBatis系列一]MyBatis入门 [深入浅出MyBatis系列二]配置 ...
- [K/3Cloud] 创建一个单据转换插件
概念: 创建一个业务单据转换插件,在单据转换的各个时点干预单据转换的相关逻辑控制. 示例: 新建一个类,继承自单据转换插件基类Kingdee.BOS.Core.Metadata.ConvertElem ...
最新文章
- 图数据库Titan安装与部署
- 《Windows PowerShell实战指南(第2版)》——1.5 安装Windows PowerShell
- eclipse 面包屑开关 / 查看class再哪个jar中
- 玩转Linux压缩及归档
- SAP Spartacus central Travis build的lint环节
- 兄弟,就你这智商就别出轨了吧?
- gson 入门_Google GSON入门
- tensorFlow13卷积神经网络发展
- 最快学习之Vue Route
- oracle数据库数据消失,,保存在数据库里的数据莫名其妙的消失
- mysql提高count_mysql count提高方法总结
- 软件项目开发文档 模板
- 手把手带你玩转Spark机器学习-Spark的安装及使用
- python 视频转图片
- 为什么大多公司不要培训班培训出来的Java程序员?
- OpenCV(二) —— 颜色通道提取 边界填充 数值计算 图像融合
- 解这道考研题要用克莱默法则的公式吗?
- meta camp+21春季PAT乙级反思
- sql中大于等于小于的写法
- iTunes Connect 上架 -- App store 搜索不到 解决方法
热门文章
- java环境变量设置 成功_java环境变量设置
- 问题:python3关于json文件多余一行后发生的错误
- Python中JSON的基本使用
- c++ 输入输出流 ios::out 和ios::trunc有什么区别
- java 线上运维_一次java应用线上运维实战
- python办公实用功能_【一点资讯】实用办公技巧贴——当Python遇上PDF www.yidianzixun.com...
- 学习使用 Manifest
- 【题解】luogu P1757 通天之分组背包
- springBoot整合Ehcache——工具类调用
- STL - bitset