ComboBox自定义实现(Realization of the DataGridView-plugin in ComboBox)


          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中,看看效果如何。


全部代码如下: 在这儿 




   

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值