public partial class UComboBoxEx : ComboBox
{
private System.Windows.Forms.ListBox lbMain;
public UComboBoxEx()
{
InitializeComponent();
lbMain = new ListBox();
lbMain.Click += new EventHandler(lbMain_Click);
lbMain.KeyDown += new KeyEventHandler(lbMain_KeyDown);
lbMain.Visible = false;
}
public UComboBoxEx(IContainer container)
{
container.Add(this);
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;
string strSelItem ="";
for (int i = 0; i < iCount; i++)
{
if (this.Items[i] is DataRowView)
{
strSelItem = (this.Items[i] as DataRowView)[this.DisplayMember].ToString();
}
else
{
strSelItem = this.Items[i].ToString();
}
if (strSelItem.Length < iLen)
continue;
if (strSelItem.IndexOf(strValue, 0, StringComparison.OrdinalIgnoreCase) >= 0 || GetChineseSpell(strSelItem).IndexOf(strValue, 0, StringComparison.OrdinalIgnoreCase) >= 0)
alReturn.Add(strSelItem);
}
return alReturn;
}
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;
}
protected override void OnTextChanged(EventArgs e)
{
if (!DesignMode)
{
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 && this.Focused)
lbMain.Visible = true;
}
base.OnTextChanged(e);
}
protected override void OnLocationChanged(EventArgs e)
{
if (!DesignMode)
{
if (lbMain != null)
{
SetlbMainLocation();
}
}
}
private void SetlbMainLocation()
{
lbMain.Visible = false;
lbMain.Width = this.Width;
lbMain.Height = 100;
lbMain.Top = this.Top + this.Height + 1;
lbMain.Left = this.Left;
lbMain.BringToFront();
}
protected override void OnLeave(EventArgs e)
{
if (!DesignMode)
{
if (!lbMain.Focused && !this.Focused)
lbMain.Visible = false;
}
base.OnLeave(e);
}
protected override void OnDropDown(EventArgs e)
{
lbMain.Visible = false;
base.OnDropDown(e);
}
protected override void OnVisibleChanged(EventArgs e)
{
if (!DesignMode)
{
if (!this.Visible)
{
if (lbMain != null)
{
lbMain.Visible = false;
}
}
}
base.OnVisibleChanged(e);
}
protected override void OnKeyDown(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;
}
}
base.OnKeyDown(e);
}
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 UComboBoxEx_SelectedIndexChanged(object sender, System.EventArgs e)
{
if (!DesignMode)
{
lbMain.Visible = false;
}
}
static public string GetChineseSpell(string strText)
{
int len = strText.Length;
string myStr = "";
for (int i = 0; i < len; i++)
{
myStr += getSpell(strText.Substring(i, 1));
}
return myStr;
}
static public string getSpell(string cnChar)
{
byte[] arrCN = Encoding.Default.GetBytes(cnChar);
if (arrCN.Length > 1)
{
int area = (short)arrCN[0];
int pos = (short)arrCN[1];
int code = (area << 8) + pos;
int[] areacode = { 45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481 };
for (int i = 0; i < 26; i++)
{
int max = 55290;
if (i != 25) max = areacode[i + 1];
if (areacode[i] <= code && code < max)
{
return Encoding.Default.GetString(new byte[] { (byte)(65 + i) });
}
}
return "*";
}
else
return cnChar;
}
}