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
}
} 
本文介绍了一种C#扩展的TextBox控件,该控件增强了基本功能,支持直接与数据表绑定,同时提供基于拼音码的辅助输入功能,方便用户快速查找和输入数据。
395

被折叠的 条评论
为什么被折叠?



