Winform(C#)实现下拉列表显示表格(利用自定义组件)

在Winform应用中,如果需要在下拉列表中显示表格(如点击 ComboBox 控件时显示一个 DataGridView 控件),可以通过自定义组件实现这一效果,而不必依赖第三方控件。下面介绍如何实现这一功能。

实现效果如下:

1. 创建自定义组件

首先,我们需要创建一个继承自 ComboBox 的自定义组件。通过这个组件,我们可以实现下拉框内显示表格的效果。代码如下:

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Design;

namespace WindowsApplication21
{
    public class ComboBoxDataGridView : ComboBox
    {
        #region 成员变量
        private const int WM_LBUTTONDOWN = 0x201, WM_LBUTTONDBLCLK = 0x203;
        ToolStripControlHost dataGridViewHost;
        ToolStripDropDown dropDown;
        private string m_sDefaultColumn;
        private string m_Separator = "|";
        private bool m_blPopupAutoSize = false;
        private DataGridViewRow m_dgvRow;
        public event EventHandler AfterSelector;
        #endregion
        #region 构造函数
        public ComboBoxDataGridView()
        {

            DrawDataGridView();

        }
        #endregion
        #region 属性
        [Description("设置DataGridView属性"), Browsable(true), Category("N8")]
        public DataGridView DataGridView
        {
            get
            {
                return dataGridViewHost.Control as DataGridView;
            }
        }
        [Description("下拉表格尺寸是否为自动"), Browsable(true), Category("N8")]
        public bool PopupGridAutoSize
        {
            set
            {
                m_blPopupAutoSize = value;
            }
        }
        [Description("分割符号"), Browsable(true), Category("N8")]
        public string SeparatorChar
        {
            set
            {
                m_Separator = value;
            }
        }
        [Description("设置默认值"), Browsable(true), Category("N8")]
        public string DefaultColumn
        {
            set
            {
                m_sDefaultColumn = value;
            }
            get
            {
                if (m_sDefaultColumn == null)
                {
                    return String.Empty;
                }
                else
                {
                    return m_sDefaultColumn;
                }
            }
        }
        #endregion
         #region 方法
        #region 绘制DataGridView以及下拉DataGridView
        private void DrawDataGridView()
        {
            DataGridView dataGridView = new DataGridView();

            dataGridView.BackgroundColor = SystemColors.ActiveCaptionText;
            dataGridView.BorderStyle = BorderStyle.None;
            dataGridView.ReadOnly = true;
            dataGridView.AllowUserToAddRows = false;
            dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView.DoubleClick += new EventHandler(dataGridView_DoubleClick);

            //设置DataGridView的数据源
            Form frmDataSource = new Form();
            frmDataSource.Controls.Add(dataGridView);
            frmDataSource.SuspendLayout();

            dataGridViewHost = new ToolStripControlHost(dataGridView);
            dataGridViewHost.AutoSize = m_blPopupAutoSize;

            dropDown = new ToolStripDropDown();
            dropDown.Width = this.Width;
            dropDown.Items.Add(dataGridViewHost);
        }
        #endregion
        public string GetDataProperty(string sColumn)
        {
            string sValue = "";
            if (m_dgvRow != null)
            {
                if (DataGridView.Columns.Contains(sColumn))
                {
                    sValue = m_dgvRow.Cells[sColumn].Value.ToString();
                }
            }
            return sValue;
        }
        public void dataGridView_DoubleClick(object sender, EventArgs e)
        {
            PopupGridView(e);
        }
        /// <summary>
        /// 弹出下拉表格并触发选择后事件
        /// </summary>
        /// <param name="e"></param>
        private void PopupGridView(EventArgs e)
        {
            if (DataGridView.SelectedRows.Count > 0)
            {

                m_dgvRow = DataGridView.SelectedRows[0];
                if (m_sDefaultColumn != String.Empty)
                {
                    Text = "";
                    string[] sColumnList = m_sDefaultColumn.Split(',');
                    foreach (string sColumn in sColumnList)
                    {
                        if (DataGridView.Columns.Contains(sColumn))
                        {
                            Text += m_dgvRow.Cells[sColumn].Value.ToString() + m_Separator;
                        }
                    }
                    Text = Text.TrimEnd(m_Separator.ToCharArray());
                }
                else
                {
                    Text = m_dgvRow.Cells[0].Value.ToString();
                }
                if (AfterSelector != null)
                {
                    AfterSelector(this,e);
                }
            }
            dropDown.Close();
        }
      
        private void ShowDropDown()
        {
            if (dropDown != null)
            {
                dataGridViewHost.Size = new Size(DropDownWidth - 2, DropDownHeight);
                dropDown.Show(this, 0, this.Height);
            }
        }
        #region 重写方法
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDBLCLK || m.Msg == WM_LBUTTONDOWN)
            {
                ShowDropDown();
                return;
            }
            base.WndProc(ref m);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (dropDown != null)
                {
                    dropDown.Dispose();
                    dropDown = null;
                }
            }
            base.Dispose(disposing);
        }
        #endregion
        #endregion

    }
}
2. 在界面中使用自定义组件

创建了自定义组件后,我们可以从工具箱中将其拖拽到界面上。然后,添加两个 TextBox 控件,分别用于显示"姓名"和"部门"。在选择下拉框中的某一行时,自动将该行的数据填充到这两个文本框中。

实现代码如下:

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Data.SqlClient;

namespace WindowsApplication21
{

    public partial class Form1 : Form
    {
       
        public Form1()
        {

            InitializeComponent();

            this.cboxdatagridview.PopupGridAutoSize = false;
            this.cboxdatagridview.DropDownHeight = 100;
            this.cboxdatagridview.DropDownWidth = 240;
            this.cboxdatagridview.DataGridView.DataSource = GetDataTable();
            this.cboxdatagridview.DefaultColumn = "编号,姓名";
            this.cboxdatagridview.AfterSelector += new EventHandler(cboxdatagridview_AfterSelector);
        }
        //选择完下拉表格后执行的事件
        private void cboxdatagridview_AfterSelector(object sender, EventArgs e)
        {
            tbName.Text = cboxdatagridview.GetDataProperty("姓名");
            tbDepartment.Text = cboxdatagridview.GetDataProperty("部门");
        }
        private DataTable GetDataTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("编号");
            dt.Columns.Add("姓名");
            dt.Columns.Add("部门");

            DataRow one = dt.NewRow();
            one["编号"] = "1001";
            one["姓名"] = "小刘";
            one["部门"] = "销售部";
            dt.Rows.Add(one);

            DataRow two = dt.NewRow();
            two["编号"] = "1002";
            two["姓名"] = "小张";
            two["部门"] = "财务部";
            dt.Rows.Add(two);

            DataRow s3 = dt.NewRow();
            s3["编号"] = "1003";
            s3["姓名"] = "三哥";
            s3["部门"] = "财务部";

            dt.Rows.Add(s3);

            return dt;

        }
    }
}
总结

通过上述步骤,我们实现了点击下拉列表时显示表格的功能,而且没有使用任何第三方控件。通过自定义组件,不仅提高了灵活性,也使得实现过程更加简便和高效。

源码地址:https://download.csdn.net/download/weixin_44643352/90056122?spm=1001.2014.3001.5503

相关推荐
不会C语言的男孩7 小时前
C++ Primer 第3章:字符串、向量和数组
开发语言·c++
兰令水7 小时前
leecodecode【反前后指针】【2026.5.31打卡-java版本】
java·开发语言
Dovis(誓平步青云)7 小时前
《QT学习第四篇:常见事件与UDP、TCP、文件系统、(锁、信号量、条件变量》
c语言·开发语言·汇编·qt
isyangli_blog16 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb20081116 小时前
FastAPI APIRouter
开发语言·python
Benszen16 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆16 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木16 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
杨充17 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~17 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言