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

相关推荐
芒果爱编程3 小时前
MCU、ARM体系结构,单片机基础,单片机操作
开发语言·网络·c++·tcp/ip·算法
明明跟你说过3 小时前
【Go语言】从Google实验室走向全球的编程新星
开发语言·后端·go·go1.19
凌盛羽4 小时前
C#对Excel表csv文件的读写操作
开发语言·windows·物联网·microsoft·c#·excel
VBA63374 小时前
VBA高级应用30例应用在Excel中的ListObject对象:向表中添加注释
开发语言
Dontla4 小时前
Rust字节数组(Byte Array)Rust u8、Vec<u8>、数组切片、向量切片、字符串转字节数组转字符串、&[u8]类型:字节数组引用
开发语言·rust
走在考研路上6 小时前
Python错误处理
开发语言·python
数据小爬虫@6 小时前
Python爬虫:如何优雅地“偷窥”商品详情
开发语言·爬虫·python
CV大法好6 小时前
刘铁猛p3 C# 控制台程序引用System.Windows.Forms报错,无法引用程序集 解决方法
开发语言·c#
Days20506 小时前
uniapp小程序增加加载功能
开发语言·前端·javascript