WinForm 自动完成控件实例代码简析
发布时间:2020-12-15 04:36:37 所属栏目:百科 来源:网络整理
导读:在Web的应用方面有js的插件实现自动完成(或叫智能提示)功能,但在WinForm窗体应用方面就没那么好了。 TextBox控件本身是提供了一个自动提示功能,只要用上这三个属性: AutoCompleteCustomSource:AutoCompleteSource 属性设置为CustomSource 时要使用的 St
在Web的应用方面有js的插件实现自动完成(或叫智能提示)功能,但在WinForm窗体应用方面就没那么好了。 TextBox控件本身是提供了一个自动提示功能,只要用上这三个属性: AutoCompleteCustomSource:AutoCompleteSource 属性设置为CustomSource 时要使用的 StringCollection。 AutoCompleteMode:指示文本框的文本完成行为。 AutoCompleteSource:自动完成源,可以是 AutoCompleteSource 的枚举值之一。 就行了, 一个简单的示例如下 复制代码 代码如下: textBox1.AutoCompleteCustomSource .AddRange(new string[] { "java","javascript","js","c#","c","c++" }); textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend; textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource; 可是这种方式的不支持我们中文的简拼自动完成(如在文本框里输入"gz"就会出现"广州")。只好自己写一个支持简拼自动完成的控件了。 这是效果图
复制代码 代码如下: private TextBox _tb; private ListBox _lb; private DataTable _dt_datasource; private bool _text_lock; private string _general_text;//原始输入文本框的值 private bool _lb_kd_first_top;//listbox是否第一次到达顶部 private int _itemCount; 复制代码 代码如下: /// <summary> /// TextBox的Text属性,增加了_text_lock操作,放置触发TextChanged事件 /// </summary> private string TextBoxText { get { return _tb.Text; } set { _text_lock = true; _tb.Text = value; _text_lock = false; } } /// <summary> /// 显示在ListBox的字段名 /// </summary> public string ValueName { get; set; } /// <summary> /// 用于匹配的字段名 /// </summary> public string CodeName { get; set; } /// <summary> /// 显示提示项的数量 /// </summary> public int ItemCount { get { return _itemCount; } set { if (value <= 0) _itemCount = 1; else _itemCount = value; } } public DataTable DataSource { get { return _dt_datasource; } set { _dt_datasource = value; } } 复制代码 代码如下: public AutoComplete() { InitialControls(); } 复制代码 代码如下: void AutoComplete_Load(object sender,EventArgs e) { _tb.Width = this.Width; _lb.Width = _tb.Width; this.Height = _tb.Height-1; } void AutoComplete_LostFocus(object sender,EventArgs e) { _lb.Visible = false; this.Height = _tb.Height-1; } 复制代码 代码如下: //列表框按键事件 void _lb_KeyDown(object sender,KeyEventArgs e) { if (_lb.Items.Count == 0 || !_lb.Visible) return; if (!_lb_kd_first_top && ((e.KeyCode == Keys.Up && _lb.SelectedIndex == 0) || (e.KeyCode == Keys.Down && _lb.SelectedIndex == _lb.Items.Count))) { _lb.SelectedIndex = -1; TextBoxText = _general_text; } else { TextBoxText = ((DataRowView)_lb.SelectedItem)[ValueName].ToString(); _lb_kd_first_top = _lb.SelectedIndex != 0; } if (e.KeyCode == Keys.Enter && _lb.SelectedIndex != -1) { _lb.Visible = false; this.Height = _tb.Height; _tb.Focus(); } } //列表鼠标单击事件 void _lb_Click(object sender,EventArgs e) { if (_lb.SelectedIndex != -1) { TextBoxText = ((DataRowView)_lb.SelectedItem)[ValueName].ToString(); } _lb.Visible = false; _tb.Focus(); this.Height = _tb.Height; } 复制代码 代码如下: //文本框按键事件 void _tb_KeyDown(object sender,KeyEventArgs e) { if (_lb.Items.Count == 0||!_lb.Visible) return; bool _is_set = false; if (e.KeyCode == Keys.Up) { if (_lb.SelectedIndex <= 0) { _lb.SelectedIndex = -1; TextBoxText = _general_text; } else { _lb.SelectedIndex--; _is_set = true; } } else if (e.KeyCode == Keys.Down) { if (_lb.SelectedIndex == _lb.Items.Count - 1) { _lb.SelectedIndex = 0; _lb.SelectedIndex = -1; TextBoxText = _general_text; } else { _lb.SelectedIndex++; _is_set = true; } } else if (e.KeyCode == Keys.Enter) { _lb.Visible = false; this.Height = _tb.Height; _is_set = _lb.SelectedIndex != -1; } _lb_kd_first_top = _lb.SelectedIndex != 0; if (_is_set) { _text_lock = true; _tb.Text = ((DataRowView)_lb.SelectedItem)[ValueName].ToString(); _tb.SelectionStart = _tb.Text.Length + 10; _tb.SelectionLength = 0; _text_lock = false; } } //文本框文本变更事件 void _tb_TextChanged(object sender,EventArgs e) { if (_text_lock) return; _general_text = _tb.Text; _lb.Visible = true; _lb.Height = _lb.ItemHeight * (_itemCount+1); this.BringToFront(); _lb.BringToFront(); this.Height = _tb.Height + _lb.Height; DataTable temp_table = _dt_datasource.Clone(); string filtStr = FormatStr(_tb.Text); DataRow [] rows = _dt_datasource.Select(string.Format(GetFilterStr(),CodeName,filtStr,_lb.DisplayMember)); for (int i = 0; i < rows.Length&&i<_itemCount; i++) { temp_table.Rows.Add(rows[i].ItemArray); } _lb.DataSource = temp_table; if (_lb.Items.Count > 0) _lb.SelectedItem = _lb.Items[0]; } 复制代码 代码如下: /// <summary> /// 初始化控件 /// </summary> private void InitialControls() { _lb_kd_first_top = true; _tb = new TextBox(); _tb.Location = new Point(0,0); _tb.Margin = new System.Windows.Forms.Padding(0); _tb.Width = this.Width; _tb.TextChanged += new EventHandler(_tb_TextChanged); _tb.KeyUp += new KeyEventHandler(_tb_KeyDown); _lb = new ListBox(); _lb.Visible = false; _lb.Width = _tb.Width; _lb.Margin = new System.Windows.Forms.Padding(0); _lb.DisplayMember = ValueName; _lb.SelectionMode = SelectionMode.One; _lb.Location = new Point(0,_tb.Height); _lb.KeyUp += new KeyEventHandler(_lb_KeyDown); _lb.Click += new EventHandler(_lb_Click); this.Controls.Add(_tb); this.Controls.Add(_lb); this.Height = _tb.Height - 1; this.LostFocus += new EventHandler(AutoComplete_LostFocus); this.Leave += new EventHandler(AutoComplete_LostFocus); this.Load += new EventHandler(AutoComplete_Load); } /// <summary> /// 获取过滤格式字符串 /// </summary> /// <returns></returns> private string GetFilterStr() { //未过滤注入的字符 ' ] %任意 *任意 string filter = " {0} like '{1}%' and IsNull([{2}],' ') <> ' ' "; if (_dt_datasource.Rows[0][CodeName].ToString().LastIndexOf(';') > -1) filter = " {0} like '%;{1}%' and IsNull([{2}],' ') <> ' ' "; return filter; } /// <summary> /// 过滤字符串中一些可能造成出错的字符 /// </summary> /// <param name="str"></param> /// <returns></returns> private string FormatStr(string str) { if (string.IsNullOrEmpty(str)) return string.Empty; str = str.Replace("[","[[]").Replace("%","[%]").Replace("*","[*]").Replace("'","''"); if (CodeName == "code") str = str.Replace(" ",""); return str; } 下面是使用控件的例子 复制代码 代码如下: class Common { /// <summary> /// 生成测试数据源 /// </summary> public static DataTable CreateTestDataSoucre { get { List<KeyValuePair<string,string>> source = new List<KeyValuePair<string,string>>() { new KeyValuePair<string,string>("张三",";zs;张三;"), new KeyValuePair<string,string>("李四",";li;李四;"),string>("王五",";ww;王五;"),string>("赵六",";zl;赵六;"),string>("洗刷",";cs;csharp;c#;洗刷;"),string>("爪哇",";java;爪哇;"),string>("java",";java;"),string>("c#",";c#;cs;csharp;"),string>("javascript",";javascript;js;") }; DataTable table = new DataTable(); table.Columns.Add("id"); table.Columns.Add("name"); table.Columns.Add("code"); for (int i = 0; i < source.Count; i++) { DataRow row = table.Rows.Add(); row["id"] = i; row["name"] = source[i].Key; row["code"] = source[i].Value; } return table; } } } //............. AutoComplete ac=new AutoComplete(); ac.ValueName = "name"; ac.CodeName = "code"; ac.DataSource= Common.CreateTestDataSoucre; ac.ItemCount= 5; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |