最近因项目中要用,于是就扩展了TextBox实现输入汉字首字母简单查询。控件扩展代码很简单。但是刚开始,一直没有找到扩展入口,始终无法展现下拉框。先想通过AutoCompleteCustomSource属性改变来实现,但最终没法扩展。后又想到ComboBox但是,也不好控制。经过一天的思考后决定用TextBox + ListBox组合扩展(主要为继承至TextBox和持有ListBox;
效果先上:
最要实现代码有:
类原型public class SpellSearchBoxEx : TextBox
{
private ListBox searchList;
.....
1:
SpellSearchSource :查询数据源(汉字)
事件的绑定和选择全在属性里;
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.KeyDown += new KeyEventHandler(searchList_KeyDown);
searchList.Click += new EventHandler(searchList_Click);
searchList.MouseMove += new MouseEventHandler(searchList_MouseMove);
}
}
}
2:TextChanged事件代码
protected virtual void SpellSearchBoxEx_TextChanged(object sender, EventArgs e)
{
searchList.Items.Clear();
string str = this.Text;
foreach (string var in spellList)
{
if (SearchMode == SearchMode.Contains)
{
if (var.IndexOf(str.ToUpper()) != -1)
{
searchList.Items.Add(source[spellList.IndexOf(var)]);
}
}
else
if (var.ToUpper().StartsWith(str.ToUpper()))
for (int i = 0; i < spellList.Count; i++)
{
if (spellList[i].Equals(var) && !searchList.Items.Contains(source[i]))
{
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))
SetSearchBoxState();
}
3:控制ListBox的显示和隐藏
private void SetSearchBoxState()
if (searchList.Items.Count > 0)
searchList.BorderStyle = BorderStyle.FixedSingle;
// maxItemCount为下拉框最大显示数;
searchList.Height = ((searchList.Items.Count >= maxItemCount ? maxItemCount : searchList.Items.Count) + 1) * searchList.ItemHeight;
searchList.Parent = this.Parent;
searchList.Location = new System.Drawing.Point(this.Left, this.Bottom);
searchList.Width = this.Width;
searchList.BringToFront();
searchList.Visible = true;
else
searchList.Visible = false;
4:剩下的为:控制鼠标滑动和键盘方向键操作,很简单,主要利用ListBox的选中项为高亮显示;及在textBox LostFocus 并非ListBox获得焦点时隐藏结果控件ListBox
5:
ListBox上回车或者是点击时提交代码
protected virtual void CommitSearchList()
if (searchList.SelectedIndex > -1)
this.Text = searchList.Items[searchList.SelectedIndex].ToString();
this.Focus();
6:主体汉字检索拼音转化代码,见下:很简单,可以直接复制拿来用。
代码
本文转自破狼博客园博客,原文链接:http://www.cnblogs.com/whitewolf/archive/2009/12/03/1615975.html,如需转载请自行联系原作者