====TextBox扩展方法======
public static class Extend
{
/// <summary>
/// 自动填充box框
/// </summary>
/// <param name="tb"></param>
/// <param name="fun">提供当前输入字符,要求返回查询出的列表,此操作在单独线程中进行</param>
/// <param name="act">当前选中的对象</param>
public static void AutoComplete(this TextBox tb, Func<string, List<object>> fun, Action<object> act)
{
var lbID = tb.Name + "_AutoComplete";
var bContinue = true;
if(tb.Parent.Controls.ContainsKey(lbID))
throw new Exception("不可重复绑定自动填充控件");
ListBox lb = new ListBox();
lb.Name = lbID;
lb.Location = new Point(tb.Location.X,tb.Location.Y + tb.Height + 1);
lb.Visible = false;
lb.Width = tb.Width;
lb.Height = 0;
lb.HorizontalScrollbar = false;
lb.DoubleClick += (oo, ee) =>
{
lb.Visible = false;
act(lb.SelectedItem);
};
tb.Parent.Controls.Add(lb);
ManualResetEvent mrevent = new ManualResetEvent(false);
Thread thread = new Thread((o) =>
{
while (true)
{
if(bContinue == false)
break;
mrevent.Reset();
mrevent.WaitOne();
Thread.Sleep(200);
if (tb.Text.Trim() == string.Empty)
{
lb.Visible = false;
lb.Items.Clear();
continue;
}
var list = fun(tb.Text);
if (list.Count == 0)
continue;
Action act2 = () =>
{
lb.Items.Clear();
lb.BringToFront();
lb.Visible = true;
lb.Height = lb.ItemHeight * (list.Count + 1) + 2;
lb.Items.AddRange(list.ToArray());
};
lb.Invoke(act2);
}
});
thread.IsBackground = true;
thread.Start();
tb.KeyDown += (o, e) =>
{
if (lb.Visible == false || lb.Items.Count == 0)
return;
if (e.KeyCode != Keys.Up && e.KeyCode != Keys.Down && e.KeyCode != Keys.Enter)
return;
var index = lb.SelectedIndex >= 0 ? lb.SelectedIndex : -1;
if (e.KeyCode == Keys.Up)
index--;
else if (e.KeyCode == Keys.Down)
index++;
if (index == lb.Items.Count)
index = lb.Items.Count - 1;
else if (index == -1)
index = 0;
lb.SelectedIndex = index;
tb.Focus();
if (e.KeyCode == Keys.Enter)
{
lb.Visible = false;
act(lb.SelectedItem);
}
};
tb.KeyUp += (o, e) =>
{
if (e.KeyCode != Keys.Up && e.KeyCode != Keys.Down)
return;
tb.SelectionLength = 0;
tb.SelectionStart = tb.Text.Length + 3;
};
tb.TextChanged += (o, e) =>
{
if (tb.Text.Trim() == string.Empty)
{
lb.Visible = false;
lb.Items.Clear();
return;
}
mrevent.Set();
};
tb.Disposed += (o, e) =>
{
lb.Dispose();
bContinue = false;
mrevent.Set();
};
}
}
========实例==========
public partial class AutoCompleteBoxPanle : Form
{
public AutoCompleteBoxPanle()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
textBox1.AutoComplete(s => {
return new List<object>() { s + "@163.com", s + "@sina.com", s + "@qq.com" };
}, s =>
MessageBox.Show(s.ToString()));
}
}