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

相关推荐
黄焖鸡能干四碗16 小时前
MES生产执行制造系统建设(Java+Mysql)
java·大数据·开发语言·信息可视化·需求分析
workflower16 小时前
跨链协同制造中的服务博弈与激励机制
开发语言·软件工程·制造·需求分析·个人开发·结对编程
liulilittle16 小时前
Y组合子剖析:C++ 中的递归魔法
开发语言·c++·编程语言·函数式编程·函数式·函数编程·y组合子
金涛031918 小时前
QT-day2,信号和槽
开发语言·qt·命令模式
R-G-B1 天前
【02】C#入门到精通——C# 变量、输入/输出、类型转换
开发语言·c#·c# 变量·c#输入/输出·c#类型转换
星河队长1 天前
C# 软件加密方法,有使用时间限制,同时要防止拷贝
开发语言·c#
史迪奇_xxx1 天前
10、一个简易 vector:C++ 模板与 STL
java·开发语言·c++
2301_801252221 天前
Java中的反射
java·开发语言
Kiri霧1 天前
Rust开发环境搭建
开发语言·后端·rust
weixin-a153003083161 天前
[数据抓取-1]beautifulsoup
开发语言·python·beautifulsoup