以前在Web上实现过AutoCompleted,并且网上有现成的组件,搜一下下载下来即可使用,但是在WinForm里面就不一样了。首先,WinForm中提供AutoCompleted的功能,不过不支持汉字首字母,所以我觉得把TextBox扩展一下,来实现这样的功能。
1. 创建一个类库"TextBoxEx",然后创建一个自定义控件类,继承于TextBox:
public partial class TextBoxEx : TextBox
2. 自定义变量及说明:
①枚举变量,Contains表示包含首字母,StartWith表示以首字母开始
public enum SearchMode { Contains, StartWith };
②自动提示的下拉列表框:
private ListBox searchList = new ListBox();
③文本框的初始汉字库:
private string[] source = null;
④将初始汉字库转化为首字母所存放的空间:
private List<string> spellList = new List<string>();
3. 自定义属性,用户可以把自定义的汉字库赋给TextBoxEx
public string[] SpellSearchSource { get { return source; } set { if (value != null) { source = value; InitSourceSpell();//实现数据转化为相应拼音并存储; TextChanged += new EventHandler(SpellSearchBoxEx_TextChanged); LostFocus += new EventHandler(SpellSearchBoxEx_LostFocus); // searchList是一个ListBox,它用来显示下拉框; searchList.Font = new Font("微软雅黑", 12, FontStyle.Regular); searchList.KeyDown += new KeyEventHandler(searchList_KeyDown); searchList.Click += new EventHandler(searchList_Click); searchList.MouseMove += new MouseEventHandler(searchList_MouseMove); } } }
4. 将自定义汉字库的每个汉字的首字母存放在变量spellList中:
private void InitSourceSpell() { for(int i = 0; i < source.Length; i++) { spellList.Add(PYHelper.Default.GetPinYin(source[i], PYHelper.PyContentType.FirstLetter, PYHelper.PyStyle.FirstCapital)); } }
5. 当在TextBoxEx文本输入框中输入字母,TextBoxEx所响应的事件:
protected virtual void SpellSearchBoxEx_TextChanged(object sender, EventArgs e) { searchList.Items.Clear(); string str = this.Text; if (str == "") { SetSearchBoxState(); return; } //输入的是汉字拼音情况; for (int i = 0; i < spellList.Count;i++ ) { string var=spellList[i]; if (_searchMode == SearchMode.Contains) // SearchMode为枚举变量:StartsWith 和Contains { if (var.IndexOf(str.ToUpper()) != -1) { // spellList是先前存储转化拼音List //searchList.Items.Add(source[spellList.IndexOf(var)]); searchList.Items.Add(source[i]); } } else { if (var.ToUpper().StartsWith(str.ToUpper())) { //searchList.Items.Add(source[spellList.IndexOf(var)]); searchList.Items.Add(source[i]); } } } //输入的是汉字情况; if (Regex.IsMatch(str, "[/u4e00-/u9fa5]+")) { foreach (string var in source) { if (_searchMode == SearchMode.Contains) { if (var.ToUpper().IndexOf(str.ToUpper()) != -1 && !searchList.Items.Contains(var)) { searchList.Items.Add(var); } } else { if (var.ToUpper().StartsWith(str.ToUpper()) && !searchList.Items.Contains(var)) { searchList.Items.Add(var); } } } } SetSearchBoxState(); }
6. 当在文本框中输入汉字,设置下拉列表框的状态:
private void SetSearchBoxState() { if (searchList.Items.Count > 0) { searchList.BorderStyle = BorderStyle.FixedSingle; // maxItemCount为下拉框最大显示数; searchList.ItemHeight = 19; searchList.Height = ((searchList.Items.Count >= _maxItemCount ? _maxItemCount : searchList.Items.Count) + 1) * searchList.ItemHeight; searchList.Parent = this.Parent; //searchList.Font = new Font("微软雅黑", 12, FontStyle.Regular); searchList.Location = new System.Drawing.Point(this.Left, this.Bottom); searchList.Width = this.Width; searchList.BringToFront(); searchList.Visible = true; } else { searchList.Visible = false; } }
7. 其他函数:
protected virtual void SpellSearchBoxEx_LostFocus(object sender, EventArgs e) { searchList.Focus(); } protected virtual void searchList_KeyDown(object sender, KeyEventArgs e) { this.Text = searchList.SelectedItem.ToString(); } protected virtual void searchList_Click(object sender, EventArgs e) { this.Text = searchList.SelectedItem.ToString(); searchList.Visible = false; this.Focus(); if (!maps.ContainsKey(question)) return; picRight.Visible = this.Text.Equals(maps[question]); picWrong.Visible = !(this.Text.Equals(maps[question])); } protected virtual void searchList_MouseMove(object sender, MouseEventArgs e) { int index=e.Y / searchList.ItemHeight; if(index>=searchList.Items.Count)index=searchList.Items.Count-1; searchList.SelectedIndex = index; }
8. 汉字首字母辅助类:
9. 字符串处理类:
class StrHelper
{
///
/// 从字串的指定位置,开始截取指定长度,并返回截取的字串
///
/// 源字串
/// 起始位置
/// 指定长度
/// 返回截取的字串
public static string Mid(string str, int start, int length)
{
if (str == "") return "";
if (start < 0) start = 0;
if (length < 0) length = 0;
if (start >= str.Length) { start = 0; length = 0; }
if (start + length > str.Length) length = str.Length - start;
return str.Substring(start, length);
}
///
/// 在字串中从左向右截取指定的长度
///
/// 源字串
/// 指定长度
/// 返回截取的字串
public static string SubLeft(string str, int length)
{
return Mid(str, 0, length);
}
///
/// 在字串中从右向左截取指定的长度
///
/// 源字串
/// 指定长度
/// 返回截取的字串
public static string SubRight(string str, int length)
{
return Mid(str, str.Length - length, length);
}
}