ComboBox控件很好用,但有时希望其下拉的数据更丰富一些,不要那么单调,后来自己琢磨一下,看看能不能自定义一个,经过查找网上资料加自己整理,做出一个demo,很糙,请随便拍!
【版本信息】:Microsoft Visual Studio 2010 Ultimate(旗舰版) 版本 10.0.40219.1 SP1Rel
Microsoft .NET Framework 版本 4.0.30319 SP1Rel
废话不多话,先看效果。
【全部代码在最下方】
具体实现如下:
第一部分:控件的自定义
控件的外观实现部分:由低到高分为4层。最底下一层为ToolStripDropDown,即点击ComboBox右侧的小黑三角后呈现的这部分,最底下一层ToolStripDropDown命名为(dropDown)。第二层为两块ToolStripControlHost,其目的是盛放TextBox和DataGridView,因此两部分自定义名称textBoxHost、dataGridViewHost。第三层有两块:TextBox和Form。如下图中的③、④所示。 第四层为DataGridView,如5所示。
声明部分的代码如下:
ToolStripControlHost dataGridViewHost; //声明盛放DataGridView的ToolStripControlHost
ToolStripControlHost textBoxHost; //声明盛放TextBox的ToolStripControlHost
ToolStripDropDown dropDown; //声明dropDown
DataGridView dataGridView = new DataGridView(); //声明DataGridView
dataGridView.BorderStyle = BorderStyle.FixedSingle;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.DoubleClick+=new EventHandler(dataGridView_DoubleClick);
Form frmDataSource = new Form(); //声明Form
frmDataSource.Controls.Add(dataGridView);
TextBox testBox = new TextBox();
testBox.KeyPress += new KeyPressEventHandler(testBox_KeyPress);
testBox.TextChanged += new EventHandler(testBox_TextChanged);
textBoxHost = new ToolStripControlHost(testBox);
textBoxHost.AutoSize = true;
dataGridViewHost = new ToolStripControlHost(dataGridView);
dropDown = new ToolStripDropDown();
dropDown.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
dropDown.Items.Add(textBoxHost);
dropDown.Items.Add(dataGridViewHost);
代码添加完成后,则需要添加各种事件:
添加的事件及完整代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Permissions;
using System.Drawing;
using System.Data;
namespace MyDataGridViewPlugin
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand,Flags=SecurityPermissionFlag.UnmanagedCode)]
class DataViewPlugin : ComboBox
{
ToolStripControlHost dataGridViewHost;
ToolStripControlHost textBoxHost;
ToolStripDropDown dropDown;
public DataViewPlugin()
{
//
DataGridView dataGridView = new DataGridView();
dataGridView.BorderStyle = BorderStyle.FixedSingle;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.DoubleClick+=new EventHandler(dataGridView_DoubleClick);
Form frmDataSource = new Form();
frmDataSource.Controls.Add(dataGridView);
TextBox testBox = new TextBox();
testBox.KeyPress += new KeyPressEventHandler(testBox_KeyPress);
testBox.TextChanged += new EventHandler(testBox_TextChanged);
textBoxHost = new ToolStripControlHost(testBox);
textBoxHost.AutoSize = true;
dataGridViewHost = new ToolStripControlHost(dataGridView);
dropDown = new ToolStripDropDown();
dropDown.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
dropDown.Items.Add(textBoxHost);
dropDown.Items.Add(dataGridViewHost);
}
//文本框输入内容时,ComboBox置空
void testBox_TextChanged(object sender, EventArgs e)
{
base.Text = "";
}
//文本框输入欲查询的值,监听回车事件
void testBox_KeyPress(object sender, KeyPressEventArgs e)
{
if((int)e.KeyChar==13) //监听 回车事件
{
for (int i = 0; i < DataGridView.RowCount; i++)
{
if (TextBox.Text.ToString().Trim() == DataGridView[0, i].Value.ToString().Trim())//此处的
{
DataGridView.CurrentCell=DataGridView[0,i];
return;
}
}
MessageBox.Show("未找到以下指定文本:\n\n" + TextBox.Text.ToString().Trim(), "提示",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
//DataGridView双击返填回ComboBox
void dataGridView_DoubleClick(object sender, EventArgs e)
{
PopupGridView();
}
private void PopupGridView()
{
DataGridViewRow currentRow = DataGridView.CurrentRow;
base.Text = currentRow.Cells[0].Value.ToString();
base.Refresh();
TextBox.Text = "";
}
public DataGridView DataGridView
{
get
{
return dataGridViewHost.Control as DataGridView;
}
}
public TextBox TextBox
{
get
{
return textBoxHost.Control as TextBox;
}
}
//点击ComboBox右侧小黑三角后,出现的下拉框
public void ShowDropDown()
{
if(dropDown!=null)
{
dataGridViewHost.Height = DropDownHeight;
dataGridViewHost.Width = DropDownWidth;
dropDown.Show(this, 0, this.Height);
}
}
//下面的部分主要是处理消息,有兴趣的可以参考MSDN上关于message及message queue。具体点击这儿
//若不感兴趣,可以直接复制粘贴。学过C++的会感到比较easy
private const int WM_USER = 0x0400,
WM_REFLECT = WM_USER + 0x1c00, //自定义事件
WM_COMMAND = 0x0111,
CBN_DROPDOWN = 7;
//取高位值
public static int HIWORD(int n)
{
return (n >> 16) & 0xffff;
}
int i = 0;
//重写消息处理方法
protected override void WndProc(ref Message m)
{
if (m.Msg == (WM_REFLECT + WM_COMMAND))
{
if (HIWORD((int)m.WParam) == CBN_DROPDOWN)
{
ShowDropDown();
return;
}
}
base.WndProc(ref m);
i++;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (dropDown != null)
{
dropDown.Dispose();
dropDown = null;
}
}
base.Dispose(disposing);
}
}
}
以上就是自定义的控件的实现。
具体使用如下:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
//准备数据
DataTable myDataTable = new DataTable();
myDataTable.Columns.Add("姓名",typeof(System.String));
myDataTable.Columns.Add("年龄",typeof(System.String));
for (int i = 1; i <= 10; i++)
{
myDataTable.Rows.Add(new object[] { "张三_"+i, 6+i });
}
//自定义控件赋值
myPlug.DataGridView.DataSource = myDataTable;
this.Controls.Add(myPlug);
}
}
很简单。
有了自定控件之后,就可以随心所欲的添加到其他的控件中了。最近打算把这个自定义控件添加到DataGridView中,看看效果如何。
全部代码如下: 在这儿