public class TextBoxExt:TextBox
{
public TextBoxExt()
{
//绑定输入框事件
this.Leave += new EventHandler(TextBoxExt_Leave);
this.KeyUp += new KeyEventHandler(TextBoxExt_KeyUp);
this.DoubleClick += new EventHandler(TextBoxExt_DoubleClick);
this.Click += new EventHandler(TextBoxExt_Click);
this.ForeColor = Color.Gray;
}
#region 变量
// 展现列表
private DataGridView _DataGrid = new DataGridView();
// 宿主窗体
private Form _Form = new Form();
// 当前选择对象
private object _NowChooseValue = new object();
// 数据源列表
private List<object> _SouceList = new List<object>();
// 数据匹配代理
private Predicate<object> _NowMatchDelegate;
// 数据选择后填充输入框对象属性
private string _StrText = string.Empty;
// 数据选择后回调函数
private MethodInvoker _BackFunction;
// 是否已设置位置
private bool _IsSetPostion = false;
#endregion
#region dataGrid属性设置
private Color _ColumnHeaderColor1 = Color.DarkGray;
private Color _ColumnHeaderColor2 = Color.Snow;
private Color _SelectedRowColor1 = Color.White;
private Color _SelectedRowColor2 = Color.FromArgb(212, 208, 200);
private Color _PrimaryRowColor1 = Color.White;
private Color _PrimaryRowColor2 = Color.AliceBlue;
private Color _SecondaryRowColor1 = Color.White;
private Color _SecondaryRowColor2 = Color.White;
private int _SecondaryLength = 2;
#endregion
#region 输入框事件
private void TextBoxExt_Leave(object sender, EventArgs e)
{
_IsSetPostion = false;
_DataGrid.Visible = _Form.ActiveControl == _DataGrid;
}
private void TextBoxExt_DoubleClick(object sender, EventArgs e)
{
_DataGrid.FirstDisplayedScrollingColumnIndex = 1;
_DataGrid.Visible = true;
_IsSetPostion = false;
if (!_IsSetPostion)
{
SetDataGridPosition();
}
if (_SouceList == null)
{
return;
}
_DataGrid.DataSource = null;
_DataGrid.DataSource = _SouceList;
}
private void TextBoxExt_Click(object sender, EventArgs e)
{
_DataGrid.FirstDisplayedScrollingColumnIndex = 1;
_DataGrid.Visible = true;
_IsSetPostion = false;
FillDataGrid();
}
private void TextBoxExt_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
_NowChooseValue = null;
_DataGrid.Visible = true;
FillDataGrid();
_IsSetPostion = true;
}
#endregion
#region 属性
/// <summary>
/// 宿主窗体
/// </summary>
public Form HostForm
{
get { return _Form; }
set { _Form = value; }
}
/// <summary>
/// 展现列表
/// </summary>
public DataGridView DataGrid
{
get { return _DataGrid; }
set
{
_DataGrid = value;
_DataGrid.Width = _Form.Width*3/5;
_DataGrid.Height = 350;
_DataGrid.MultiSelect = false;
this._DataGrid.Parent = _Form;
this._Form.ResumeLayout(false);
this._DataGrid.BringToFront();
_DataGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
_DataGrid.MultiSelect = false;
_DataGrid.RowPostPaint += new DataGridViewRowPostPaintEventHandler(DataGrid_RowPostPaint);
_DataGrid.CellDoubleClick += new DataGridViewCellEventHandler(DataGrid_CellDoubleClick);
//_DataGrid.RowPrePaint+=new DataGridViewRowPrePaintEventHandler(DataGrid_RowPrePaint);
_DataGrid.CellPainting+=new DataGridViewCellPaintingEventHandler(DataGrid_CellPainting);
_DataGrid.AllowUserToAddRows = false;
_DataGrid.AllowUserToDeleteRows = false;
_DataGrid.ReadOnly = true;
_DataGrid.RowTemplate.Height = 18;
_DataGrid.AllowUserToOrderColumns = true;
_DataGrid.RowTemplate.DefaultCellStyle.ForeColor = Color.Gray;
_DataGrid.GridColor = Color.SlateGray;
_DataGrid.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
//_DataGrid.RowTemplate.DefaultCellStyle.BackColor = Color.Transparent;
_DataGrid.Leave += new EventHandler(DataGrid_Leave);
_DataGrid.BorderStyle = BorderStyle.Fixed3D;
_DataGrid.RowHeadersWidth = 50;
}
}
public List<object> SouceList
{
get { return _SouceList; }
set { _SouceList = value; }
}
public string StrText
{
get { return _StrText; }
set { _StrText = value; }
}
/// <summary>
/// 模糊搜索匹配delegate
/// </summary>
public Predicate<object> NowMatchDelegate
{
get { return _NowMatchDelegate; }
set { _NowMatchDelegate = value; }
}
public object NowChooseValue
{
get { return _NowChooseValue; }
set { _NowChooseValue = value; }
}
public int DataGridWidth
{
get { return _DataGrid.Width; }
set { _DataGrid.Width = value; }
}
public int DataGridHeight
{
get { return _DataGrid.Height; }
set { _DataGrid.Height = value; }
}
public MethodInvoker BackFunction
{
get { return _BackFunction; }
set { _BackFunction = value; }
}
#endregion
#region DataGridView 显示相关
private void DataGrid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
Rectangle rectangle = new Rectangle(e.RowBounds.Location.X,
e.RowBounds.Location.Y,
_DataGrid.RowHeadersWidth - 4,
e.RowBounds.Height);
TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
new Font("黑体", 9, FontStyle.Bold),
rectangle,
Color.Gray,
TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
}
private void DataGrid_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
Rectangle rowBounds =new Rectangle(0, e.RowBounds.Top, _DataGrid.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) -_DataGrid.HorizontalScrollingOffset + 1,e.RowBounds.Height);
e.PaintParts &= ~DataGridViewPaintParts.Focus;
if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
{
if (_DataGrid.RowTemplate.DefaultCellStyle.SelectionBackColor == Color.Transparent)
DrawLinearGradient(rowBounds, e.Graphics, _SelectedRowColor1, _SelectedRowColor2);
}
else
{
if (_DataGrid.RowTemplate.DefaultCellStyle.BackColor == Color.Transparent)
{
if (e.RowIndex % _SecondaryLength == 1)
{
DrawLinearGradient(rowBounds, e.Graphics, _PrimaryRowColor1, _PrimaryRowColor2);
}
else
{
DrawLinearGradient(rowBounds, e.Graphics, _SecondaryRowColor1, _SecondaryRowColor2);
}
}
}
}
private static void DrawLinearGradient(Rectangle Rec, Graphics Grp, Color Color1, Color Color2)
{
if (Color1 == Color2)
{
Brush backbrush = new SolidBrush(Color1);
Grp.FillRectangle(backbrush, Rec);
}
else
{
using (Brush backbrush =
new LinearGradientBrush(Rec, Color1, Color2, LinearGradientMode.Vertical))
{
Grp.FillRectangle(backbrush, Rec);
}
}
}
private void DataGrid_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == -1)
{
if (!(_ColumnHeaderColor1 == Color.Transparent) && !(_ColumnHeaderColor2 == Color.Transparent) &&
!_ColumnHeaderColor1.IsEmpty && !_ColumnHeaderColor2.IsEmpty)
{
DrawLinearGradient(e.CellBounds, e.Graphics, _ColumnHeaderColor1, _ColumnHeaderColor2);
e.Paint(e.ClipBounds, (DataGridViewPaintParts.All & ~DataGridViewPaintParts.Background));
e.Handled = true;
}
}
}
#endregion
#region DataGridView 事件相关
private void DataGrid_Leave(object sender, EventArgs e)
{
_DataGrid.Visible = false;
}
private void DataGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex !=-1)
{
SetDataGridPosition();
if (_DataGrid.SelectedRows.Count > 0)
{
object NowChooseObj = (_DataGrid.DataSource as List<object>)[e.RowIndex];
_NowChooseValue = NowChooseObj;
_DataGrid.Visible = false;
this.Text = NowChooseObj.GetType().GetProperty(_StrText).GetValue(NowChooseObj, null).ToString();
if (_BackFunction != null)
{
_Form.BeginInvoke(_BackFunction);
}
}
else
{
_NowChooseValue = null;
}
}
}
#endregion
#region 相关函数
/// <summary>
/// 填充列表
/// </summary>
private void FillDataGrid()
{
if (!_IsSetPostion)
{
SetDataGridPosition();
}
if (_SouceList == null)
{
return;
}
_DataGrid.DataSource = null;
_DataGrid.DataSource = _NowMatchDelegate != null ? _SouceList.FindAll(_NowMatchDelegate) : _SouceList;
}
/// <summary>
/// 获得子控件在父控件的坐标
/// </summary>
/// <param name="ctrl">子控件</param>
/// <param name="parentCtrl">父控件</param>
/// <returns></returns>
private Point GetPointAsParent(Control ctrl, Control parentCtrl)
{
int x, y;
x = ctrl.Location.X;
y = ctrl.Location.Y;
while (ctrl.Parent != null && !ctrl.Parent.GetType().Equals(parentCtrl.GetType()))
{
x += ctrl.Parent.Location.X;
y += ctrl.Parent.Location.Y;
ctrl = ctrl.Parent;
}
return new Point(x, y);
}
/// <summary>
/// 设置列表位置
/// </summary>
private void SetDataGridPosition()
{
Point txtPoint = GetPointAsParent(this, _Form);
//Point txtPoint = this.Location;
if (txtPoint.X + _DataGrid.Width > _Form.Width)
{
_DataGrid.Location = new System.Drawing.Point(txtPoint.X+this.Width-_DataGrid.Width<10?10:txtPoint.X - _DataGrid.Width + this.Width, txtPoint.Y + this.Height);
}else{
_DataGrid.Location = new System.Drawing.Point(txtPoint.X, txtPoint.Y + this.Height);
}
}
#endregion
}