using System; using System.Data; using System.Windows.Forms; using System.ComponentModel; namespace AuxiliaryTextBox ... { /**//// <summary> /// 扩展的文本框,支持数据表绑定,基于拼音码的辅助输入 /// </summary> public class AuliaryTextBox : TextBox ...{ 字段#region 字段 string Empty = string.Empty; ListBox popupListBox = null; // 所要用到的列表框 string displayMember; // 显示字段 string valueMember; // 值字段 DataTable valueTable; // 包含全部数据的数据表 Control nextControl; // 下一个焦点的控件 string spellCode; #endregion 构造器#region 构造器 public AuliaryTextBox() ...{ BackColor = System.Drawing.Color.WhiteSmoke; Text = Empty; this.SetStyle( ControlStyles.Opaque, true ); } #endregion 属性#region 属性 [Category( "JueJue1984" ), Description( " 指定一个辅助输入的ListBox实例,该ListBox将包含所有即将可能被输入的数据." ) ] public ListBox PopupListBox ...{ get...{ return this.popupListBox; } set...{ this.popupListBox = value; } } [Category( "JueJue1984" ), Description( " 指定一个拼音码字段." ) ] public string SpellCode ...{ get...{ return this.spellCode; } set...{ this.spellCode = value; } } [Category( "JueJue1984" ), Description( "指定作为ListBox对象项目属性的显示值字段" ) ] public string DisplayMember ...{ get...{ return this.displayMember; } set...{ this.displayMember = value; } } [Category( "JueJue1984" ), Description( "指定作为ListBox对象项目属性的的实际值字段" ) ] public string ValueMember ...{ get...{ return this.valueMember; } set...{ this.valueMember = value; } } [Browsable( false ) ] public DataTable ValueTable ...{ get...{ return this.valueTable; } set...{ this.valueTable = value; } } [Category( "JueJue1984" ), Description( "下一个Tab的控件" ) ] public Control NextControl ...{ get...{ return this.nextControl; } set...{ this.nextControl = value; } } #endregion 逻辑处理,私有方法#region 逻辑处理,私有方法 设置列表控件的状态(数据由数据表指定)#region 设置列表控件的状态(数据由数据表指定) /**//// <summary> ///◆设置列表控件的状态(数据由数据表指定) /// </summary> /// <param name="lb">▼当前正在操作的列表控件</param> /// <param name="tb">▼相关的文本框控件</param> /// <param name="keyInt">▼客户端产生的键值</param> /// <param name="dt1">▼包含全部数据的数据表</param> /// <param name="DisplayMember">▼列表控件的显示成员</param> /// <param name="ValueMember">▼列表控件的值成员</param> private static void SetListStateDataTable( ListBox lb, System.Windows.Forms.TextBox tb, int keyInt , DataTable dt1, string DisplayMember, string ValueMember, string SpellCode ) ...{ string x = tb.Text; if( x == string.Empty ) ...{ lb.Visible = false; return; } else ...{ DataTable dt = dt1.Clone(); dt.Rows.Clear(); //数字或者合法字符 if( keyInt == 8 || keyInt == 32 || (keyInt >= 48 && keyInt <= 122) ) ...{ //DataTable dt = CD.PublicMethod.GetNullTable( TableName, DisplayMember, ValueMember ); foreach( DataRow dr in dt1.Select( SpellCode + " like '" + tb.Text + "%'" ) ) ...{ dt.Rows.Add( dr.ItemArray ); } if( keyInt == 32 && x == " " ) ...{ dt.Rows.Clear(); dt = dt1; } if( dt == null || dt.Rows.Count == 0 ) ...{ lb.DataSource = null; lb.Visible = false; return; } SetListData( lb, dt, DisplayMember, ValueMember ); SetListPosition( lb, tb, tb.Parent, tb.Top, tb.Left ); //SetListWidth( lb ); lb.Visible = true; lb.SelectedIndex = 0; } else if( keyInt == 40) //Down Key ...{ if( lb.DataSource == null || lb.SelectedIndex < 0 ) ...{ VerifyValue( lb, tb ); return; } if( lb.SelectedIndex == lb.Items.Count - 1) ...{ lb.SelectedIndex = 0; } else ...{ lb.SelectedIndex += 1; } } else if( keyInt == 38)//UP Key ...{ if( lb.DataSource == null || lb.SelectedIndex <0 ) ...{ VerifyValue( lb, tb ); return; } if( lb.SelectedIndex == 0 ) ...{ lb.SelectedIndex = lb.Items.Count - 1; } else ...{ lb.SelectedIndex -= 1; } } else if ( keyInt == 13 ) ...{ if( lb.DataSource == null || lb.SelectedIndex < 0 ) ...{ VerifyValue( lb, tb ); return; } else ...{ tb.Text = lb.Text; tb.Tag = lb.SelectedValue; lb.Visible = false; } } else ...{ return; } } } #endregion 动态设置列表控件的宽度#region 动态设置列表控件的宽度 /**//// <summary> /// ◆ 动态设置列表控件的宽度 /// </summary> /// <param name="lb">▼列表控件</param> private static void SetListWidth( ListBox lb ) ...{ object a = "22"; foreach( object lvm in lb.Items ) ...{ if( lb.GetItemText( lvm ).Length > a.ToString().Length ) ...{ a = lvm; } } lb.Width = a.ToString().Length * 9 + 44; } #endregion 将数据表内容填充到列表控件里#region 将数据表内容填充到列表控件里 /**//// <summary> /// ◆ 将数据表内容填充到列表控件里 /// </summary> /// <param name="lb">▼列表控件</param> /// <param name="dt">▼数据表</param> /// <param name="DisplayMember">▼显示成员</param> /// <param name="ValueMember">▼值成员</param> private static void SetListData( ListBox lb, DataTable dt, string DisplayMember, string ValueMember ) ...{ lb.DataSource = dt; lb.DisplayMember = DisplayMember; lb.ValueMember = ValueMember; } #endregion 动态设置列表控件的位置#region 动态设置列表控件的位置 /**//// <summary> /// ◆ 动态设置列表控件的位置 /// </summary> /// <param name="lb">▼相关的列表控件</param> /// <param name="tb">▼相关的文本框控件</param> /// <param name="parentCtrl">▼</param> /// <param name="oppositeTop">▼在父控件中的相对纵坐标</param> /// <param name="oppositeLeft">▼在父控件中的相对横坐标</param> private static void SetListPosition( ListBox lb, System.Windows.Forms.TextBox tb, System.Windows.Forms.Control parentCtrl, int oppositeTop, int oppositeLeft ) ...{ //将网格放在触发文本框上面或下面都不合适 if(parentCtrl.Height<lb.Height+tb.Height+oppositeTop && oppositeTop<lb.Height) ...{ 高度不适合#region 高度不适合 if(parentCtrl.Parent!=null) ...{ SetListPosition(lb,tb, parentCtrl.Parent,oppositeTop+parentCtrl.Top,oppositeLeft+parentCtrl.Left); } #endregion } else ...{ 高度适合#region 高度适合 lb.Parent = parentCtrl; lb.BringToFront(); if(parentCtrl.Height<lb.Height+tb.Height+oppositeTop) //如果其下边界超出父容器底边界则底部与父容器底边界对齐 ...{ lb.Top =oppositeTop-lb.Height; } else ...{ lb.Top =oppositeTop+tb.Height; } if(parentCtrl.Width<lb.Width+oppositeLeft) ...{ lb.Left =oppositeLeft-(lb.Width-tb.Width); if(lb.Left<0) //宽度不适合 ...{ if(parentCtrl.Parent!=null) ...{ SetListPosition(lb, tb,parentCtrl.Parent,oppositeTop+parentCtrl.Top,oppositeLeft+parentCtrl.Left); } } } else ...{ lb.Left =oppositeLeft; } #endregion } } #endregion 判断是否数据源为NULL#region 判断是否数据源为NULL /**//// <summary> /// ◆ 判断是否数据源为NULL /// </summary> /// <param name="lb">▼列表控件</param> /// <param name="tb">▼文本框</param> private static void VerifyValue( ListBox lb, TextBox tb ) ...{ tb.Text = ""; tb.Tag = null; lb.Visible = false; } #endregion #endregion 原始方法#region 原始方法 /**//* /// <summary> ///◆ ListBox控件发生双击事件时,设置对应文本框控件的值和ListBox控件的状态 /// </summary> /// <param name="textBox1">▼相关文本框控件</param> /// <param name="listBox1">▼相关列表控件</param> public static void SetCorrespondingTextBoxDC( TextBox textBox1, ListBox listBox1 ) { textBox1.Text = listBox1.GetItemText( listBox1.SelectedItem ); //取显示值 textBox1.Tag = listBox1.SelectedValue; //取实际值 listBox1.Visible = false; //设置为不可视 } /// <summary> /// ◆ ListBox控件发生回车事件时,设置对应文本框控件的值和ListBox控件的状态 /// </summary> /// <param name="textBox1">▼相关文本框控件</param> /// <param name="listBox1">▼相关列表控件</param> /// <param name="KeyValue">▼按键值</param> public static void SetCorrespondingTextBoxKD( TextBox textBox1, ListBox listBox1, int KeyValue ) { if( KeyValue == 13 ) { textBox1.Text = listBox1.GetItemText( listBox1.SelectedItem ); //取显示值 textBox1.Tag = listBox1.SelectedValue; //取实际值 listBox1.Visible = false; //设置为不可视 } } /// <summary> /// ◆ 当TextBox控件的内容被改变后,设置对应文本框控件的值和ListBox控件的状态 /// </summary> /// <param name="tbDepartmentID">▼相关文本框控件</param> /// <param name="colorfulListBox1">▼相关列表控件</param> /// <param name="x">▼相关文本框的内容</param> public static void SetCorrespondingTextBoxTC( TextBox tbDepartmentID, ListBox colorfulListBox1, string x ) { if( x == NULL ) { tbDepartmentID.Tag = NULL; colorfulListBox1.Visible = false; } } /// <summary> /// ◆在TextBox控件中键入数据后ListBox的反应和其它关联控件的状态设置 /// </summary> /// <param name="tbDepartmentID">▼相关TextBox控件</param> /// <param name="colorfulListBox1">▼相关ListBox控件</param> /// <param name="KeyValue">▼按键值</param> /// <param name="dt">▼表名</param> /// <param name="DisplayMember">▼显示字段</param> /// <param name="ValueMember">▼值字段</param> /// <param name="btOk">▼TextBox控件的下一个控件</param> public static void SetCorrespondingTextBoxKU( TextBox tbDepartmentID, ListBox colorfulListBox1, int KeyValue, DataTable dt, string DisplayMember, string ValueMember, Control btOk ) { if( tbDepartmentID.Tag == null || tbDepartmentID.Tag.ToString() == NULL ) { SetListStateDataTable( colorfulListBox1, tbDepartmentID, KeyValue, dt, DisplayMember, ValueMember ); } else { CD.PublicMethod.SetFocus( btOk, KeyValue ); } } */ #endregion 重载方法#region 重载方法 /**//// <summary> /// ◆ ListBox控件发生双击事件时,设置对应文本框控件的值和ListBox控件的状态 /// </summary> /// <param name="e">wow</param> protected override void OnDoubleClick(EventArgs e) ...{ base.OnDoubleClick (e); Text = popupListBox.GetItemText( popupListBox.SelectedItem ); Tag = popupListBox.SelectedValue; popupListBox.Visible = false; } /**//// <summary> /// ◆ ListBox控件发生回车事件时,设置对应文本框控件的值和ListBox控件的状态 /// </summary> /// <param name="e">wow</param> protected override void OnKeyDown(KeyEventArgs e) ...{ base.OnKeyDown (e); if( e.KeyValue == 13 ) ...{ Text = popupListBox.GetItemText( popupListBox.SelectedItem ); //取显示值 Tag = popupListBox.SelectedValue; //取实际值 popupListBox.Visible = false; //设置为不可视 } } /**//// <summary> /// ◆ 当TextBox控件的内容被改变后,设置对应文本框控件的值和ListBox控件的状态 /// </summary> /// <param name="e">wow</param> protected override void OnTextChanged(EventArgs e) ...{ base.OnTextChanged (e); if( Text == Empty ) ...{ Tag = null; popupListBox.Visible = false; } }/**//// <summary>/// /// </summary>/// <param name="e"></param> protected override void OnKeyUp(KeyEventArgs e) ...{ base.OnKeyUp (e); if( Tag == null || Tag.ToString() == Empty ) ...{ SetListStateDataTable( popupListBox, this, e.KeyValue, valueTable, displayMember, valueMember, SpellCode ); } else ...{ if( e.KeyValue == 13 ) ...{ nextControl.Focus(); } } } #endregion }}