此程序使用Window应用程序设计的,此程序是作者自己建立的textbox,
他建立了AutoCompleteTextbox和CoolTextBox,用它来完成
首先我先对用户输入时出现的下拉框和匹配文字的关键字进行说明:
此程序完成匹配关键字的代码如下:
// Add some sample auto complete entry items...
this.coolTextBox1.Items.Add(new AutoCompleteEntry("Phoenix, Az", "Phoenix, Az", "Az", "PHX"));
this.coolTextBox1.Items.Add(new AutoCompleteEntry("Tempe, Az", "Tempe, Az", "Az", "TPE"));
this.coolTextBox1.Items.Add(new AutoCompleteEntry("Chandler, Az", "Chandler, Az", "Az", "CHA"));
this.coolTextBox1.Items.Add(new AutoCompleteEntry("Boxford, Ma", "Boxford, Ma", "Ma", "BXF"));
this.coolTextBox1.Items.Add(new AutoCompleteEntry("Topsfield, Ma", "Topsfield, Ma", "Ma", "TPF"));
this.coolTextBox1.Items.Add(new AutoCompleteEntry("Danvers, Ma", "Danvers, Ma", "Ma", "DNV"));
当你输入会出现下拉框,其中下拉框会出现蓝色的,此蓝色文字就是你所匹配的文字。
下面我对当你输入一个是什么么不出现匹配的关键字做说明:
此程序控制关键字的代码如下:
public class TextLengthTrigger : AutoCompleteTrigger
{
private int textLength = 2;
public int TextLength
{
get
{
return this.textLength;
}
set
{
this.textLength = value;
}
}
public TextLengthTrigger()
{
}
public TextLengthTrigger(int length)
{
this.textLength = length;
}
public override TriggerState OnTextChanged(string text)
{
if (text.Length >= this.TextLength)
return TriggerState.Show;
else if (text.Length < this.TextLength)
return TriggerState.Hide;
return TriggerState.None;
}
}
}
当你把上面的private int textLength = 2;改掉,它也不会出现一个关键字,原因是在作者改掉,是此程序出现的debug。其代码如下:
this.triggers.Add(new TextLengthTrigger(2));当你改掉这里时他就好了。
CoolTextBox:CoolTextBox是作者自己定义的,CoolTextBox这个类是对你输入的文本框进行涂色,其代码如下:
private Color borderColor = Color.LightSteelBlue;
public Color BorderColor
{
get
{
return this.borderColor;
}
set
{
if (this.borderColor != value)
{
this.borderColor = value;
this.Invalidate();
}
}
}
[Browsable(true)]
public override string Text
{
get
{
return this.autoCompleteTextBox1.Text;
}
set
{
this.autoCompleteTextBox1.Text = value;
}
}
public override Color ForeColor
{
get
{
return this.autoCompleteTextBox1.ForeColor;
}
set
{
this.autoCompleteTextBox1.ForeColor = value;
}
}
public override ContextMenu ContextMenu
{
get
{
return this.autoCompleteTextBox1.ContextMenu;
}
set
{
this.autoCompleteTextBox1.ContextMenu = value;
}
}
private AutoCompleteTextBox autoCompleteTextBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public CoolTextBox()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
Rectangle rect = this.ClientRectangle;
rect.Width -= 1;
rect.Height -= 1;
Pen p = new Pen(this.BorderColor);
e.Graphics.DrawRectangle(p, rect);
p = new Pen(Color.FromArgb(100, this.BorderColor));
rect.Inflate(-1, -1);
e.Graphics.DrawRectangle(p, rect);
p = new Pen(Color.FromArgb(45, this.BorderColor));
rect.Inflate(-1, -1);
e.Graphics.DrawRectangle(p, rect);
p = new Pen(Color.FromArgb(15, this.BorderColor));
rect.Inflate(-1, -1);
e.Graphics.DrawRectangle(p, rect);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
private void InitializeComponent()
{
this.autoCompleteTextBox1 = new AutoCompleteTextBox();
this.SuspendLayout();
this.autoCompleteTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.autoCompleteTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.autoCompleteTextBox1.Location = new System.Drawing.Point(4, 4);
this.autoCompleteTextBox1.Name = "autoCompleteTextBox1";
this.autoCompleteTextBox1.PopupBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.autoCompleteTextBox1.PopupOffset = new System.Drawing.Point(12, 4);
this.autoCompleteTextBox1.PopupSelectionBackColor = System.Drawing.SystemColors.Highlight;
this.autoCompleteTextBox1.PopupSelectionForeColor= System.Drawing.SystemColors.HighlightText;
this.autoCompleteTextBox1.PopupWidth = 120;
this.autoCompleteTextBox1.Size = new System.Drawing.Size(120, 13);
this.autoCompleteTextBox1.TabIndex = 0;
this.autoCompleteTextBox1.Text = "autoCompleteTextBox1";
this.autoCompleteTextBox1.SizeChanged += new System.EventHandler(this.TextBox_SizeChanged);
//
// CoolTextBox
//
this.BackColor = System.Drawing.SystemColors.Window;
this.Controls.Add(this.autoCompleteTextBox1);
this.DockPadding.All = 4;
this.Name = "CoolTextBox";
this.Size = new System.Drawing.Size(128, 22);
this.ResumeLayout(false);
}
#endregion
private void TextBox_SizeChanged(object sender, System.EventArgs e)
{
AutoCompleteTextBox tb = sender as AutoCompleteTextBox;
this.Height = tb.Height + 8;
}
}
}
当你改变里面的数值,他就会变色,(注:你输入的数值要在一定的范围内)
TriggerState:这个类是枚举。
我在上一次写到了,当你没有输入任何东西时,你点击鼠标正文本框时他就会变色,
因此有我们需要确定的几个地方鼠标是否在正文框或弹开之外点击了,
我们需要捉住正文框的OnLostFocus,并且撤销事件弹开 ,其代码如下:
protected override void OnLostFocus(EventArgs e)
{ base.OnLostFocus (e);
if (!(this.Focused || this.popup.Focused || this.list.Focused))
{
this.HideList();
}
}
private void Popup_Deactivate(object sender, EventArgs e)
{ if (!(this.Focused || this.popup.Focused || this.list.Focused))
{
this.HideList();
}
}
那些是容易部分。 现在我们需要设陷井去形式文本框居住和它的儿童控制的所有老鼠事件。 这是更加困难的。 做我使用NativeWindow作为基类为我的老鼠勾子的此
我然后细听了所有鼠标点击事件。 如果鼠标点击在正文框的边界框之内发生了,则弹开保持可看见。 否则,我们应该掩藏弹开。
private class WinHook : NativeWindow
{
private AutoCompleteTextBox tb;
public WinHook(AutoCompleteTextBox tbox)
{
this.tb = tbox;
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case Win32.Messages.WM_LBUTTONDOWN:
case Win32.Messages.WM_LBUTTONDBLCLK:
case Win32.Messages.WM_MBUTTONDOWN:
case Win32.Messages.WM_MBUTTONDBLCLK:
case Win32.Messages.WM_RBUTTONDOWN:
case Win32.Messages.WM_RBUTTONDBLCLK:
case Win32.Messages.WM_NCLBUTTONDOWN:
case Win32.Messages.WM_NCMBUTTONDOWN:
case Win32.Messages.WM_NCRBUTTONDOWN:
{
Form form = tb.FindForm();
Point p = form.PointToScreen(new Point((int)m.LParam)); Point p2 = tb.PointToScreen(new Point(0, 0));
Rectangle rect = new Rectangle(p2, tb.Size);
if (!rect.Contains(p))
{
tb.HideList();
}
} break;
case Win32.Messages.WM_SIZE:
case Win32.Messages.WM_MOVE:
{
tb.HideList();
} break;
case Win32.Messages.WM_PARENTNOTIFY:
{
switch ((int)m.WParam)
{ case Win32.Messages.WM_LBUTTONDOWN:
case Win32.Messages.WM_LBUTTONDBLCLK:
case Win32.Messages.WM_MBUTTONDOWN:
case Win32.Messages.WM_MBUTTONDBLCLK:
case Win32.Messages.WM_RBUTTONDOWN:
case Win32.Messages.WM_RBUTTONDBLCLK:
case Win32.Messages.WM_NCLBUTTONDOWN:
case Win32.Messages.WM_NCMBUTTONDOWN:
case Win32.Messages.WM_NCRBUTTONDOWN:
{
Form form = tb.FindForm();
Point p = form.PointToScreen(new Point((int)m.LParam));
Point p2 = tb.PointToScreen(new Point(0, 0));
Rectangle rect = new Rectangle(p2, tb.Size);
if (!rect.Contains(p))
{
tb.HideList();
}
} break;
}
} break;
}
base.WndProc (ref m);
}
}