根据你输入的内容自动过滤出匹配的列表项,并实时显示出来,和IE地址栏类似。
程序很简单,只是很长事时间没更新blog了,用这篇小文章来更新一下。
程序原理是这样的:组件继承之combobox,并且拥有一个listbox成员,当组件的text改变时,就从combobox中过滤出匹配的列表项,并且把这些列表项加入到listbox中显示出来。
演示效果:
using System;using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace XPangLib
{
/// <summary>
/// AutoComboBox 的摘要说明。
/// </summary>
public class AutoComboBox : System.Windows.Forms.ComboBox
{
private System.Windows.Forms.ListBox lbMain;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public AutoComboBox()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
lbMain = new ListBox() ;
lbMain.Click+=new EventHandler(lbMain_Click);
lbMain.KeyDown+=new KeyEventHandler(lbMain_KeyDown);
lbMain.Visible = false ;
}
/// <summary>
/// 得到匹配给定字符串的列表
/// </summary>
private ArrayList GetFillList(string strValue)
{
ArrayList alReturn = new ArrayList() ;
int iCount = this.Items.Count ;
int iLen = strValue.Length ;
for(int i = 0 ;i < iCount ;i++)
{
string strSelItem = this.Items[i].ToString() ;
if (strSelItem.Length < iLen)
continue ;
if (strSelItem.Substring(0,iLen) == strValue)
alReturn.Add(strSelItem) ;
}
return alReturn ;
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{//
// AutoComboBox
//
this.Sorted = true;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AutoComboBox_KeyDown);
this.DropDown += new System.EventHandler(this.AutoComboBox_DropDown);
this.TextChanged += new System.EventHandler(this.AutoComboBox_TextChanged);
this.SelectedIndexChanged += new System.EventHandler(this.AutoComboBox_SelectedIndexChanged);
this.Leave += new System.EventHandler(this.AutoComboBox_Leave);
}
#endregion
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此添加自定义绘画代码
// 调用基类 OnPaint
base.OnPaint(pe);
}
private void lbMain_Click(object sender, System.EventArgs e)
{
if (lbMain.SelectedItems.Count == 0)
return ;
string strSel = lbMain.SelectedItem.ToString() ;
this.Text = strSel ;
int iSel = this.FindStringExact(Text) ;
if (iSel != -1)
this.SelectedIndex = iSel ;
lbMain.Visible = false ;
}
private void AutoComboBox_TextChanged(object sender, System.EventArgs e)
{
if (Text == "")
{
lbMain.Visible = false ;
return ;
}
if (!this.Parent.Controls.Contains(lbMain))
{
lbMain.Width = this.Width ;
lbMain.Height = 100 ;
lbMain.Parent = this.Parent ;
lbMain.Top = this.Top + this.Height + 1 ;
lbMain.Left = this.Left ;
this.Parent.Controls.Add(lbMain);
lbMain.BringToFront() ;
}
ArrayList alFill = GetFillList(Text) ;
lbMain.Items.Clear() ;
lbMain.Items.AddRange(alFill.ToArray()) ;
if (lbMain.Items.Count > 0)
lbMain.SelectedIndex = 0 ;
if (!lbMain.Visible)
lbMain.Visible = true ;
}
private void AutoComboBox_Leave(object sender, System.EventArgs e)
{
if (!lbMain.Focused)
lbMain.Visible = false ;
}
private void AutoComboBox_DropDown(object sender, System.EventArgs e)
{
lbMain.Visible = false ;
}
private void AutoComboBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (lbMain.Visible)
{
if (e.KeyCode == Keys.Up||e.KeyCode == Keys.Down||e.KeyCode == Keys.Left||
e.KeyCode == Keys.Right||e.KeyCode == Keys.PageDown||e.KeyCode == Keys.PageUp)
{
lbMain_KeyDown(lbMain,e) ;
e.Handled = true ;
}
else if (e.KeyCode == Keys.Enter)
{
lbMain_Click(lbMain,e) ;
e.Handled = true ;
}
}
}
private void lbMain_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Up||e.KeyCode == Keys.Left||e.KeyCode == Keys.PageUp)
{
if (lbMain.SelectedIndex > 0)
lbMain.SelectedIndex = lbMain.SelectedIndex - 1 ;
}
else if (e.KeyCode == Keys.Down||e.KeyCode == Keys.Right||e.KeyCode == Keys.PageDown)
{
if (lbMain.SelectedIndex < lbMain.Items.Count - 1)
lbMain.SelectedIndex = lbMain.SelectedIndex + 1 ;
}
}
private void AutoComboBox_SelectedIndexChanged(object sender, System.EventArgs e)
{
lbMain.Visible = false ;
}
}//end class
}//end namespace