在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