如何在编辑DataGridView单元格时弹出ComboBox并点击时选中整行
问题描述
在WinForms的DataGridView中,已手动创建列并实现了DataGridViewComboBoxColumn从数据库选项选择填充单元格的功能,但点击ComboBox控件时,无法自动选中所在的整行,导致RowEnter事件执行出错,需要实现点击ComboBox时自动选中其所在的整行。
已实现的核心代码如下:
列创建代码
DataGridViewTextBoxColumn colCategory = new(); DataGridViewTextBoxColumn colCategoryId = new(); DataGridViewTextBoxColumn colComponentId = new(); DataGridViewTextBoxColumn colPartNumber = new(); DataGridViewTextBoxColumn colDescription = new(); DataGridViewTextBoxColumn colPackage = new(); DataGridViewTextBoxColumn colManufacturerId = new(); DataGridViewTextBoxColumn colLifecycleId = new(); DataGridViewComboBoxColumn comboColManufacturer = new(); DataGridViewComboBoxColumn comboColLifecycle = new(); dgProducts.AutoGenerateColumns = false; colCategory.HeaderText = "category"; colCategoryId.HeaderText = "category_id"; colComponentId.HeaderText = "component_id"; colPartNumber.HeaderText = "part_number"; colDescription.HeaderText = "description"; colPackage.HeaderText = "package"; colManufacturerId.HeaderText = "manufacturer_id"; colLifecycleId.HeaderText = "lifecycle_id"; comboColManufacturer.HeaderText = "manufacturer"; comboColLifecycle.HeaderText = "lifecycle"; colCategory.DataPropertyName = "category"; colCategoryId.DataPropertyName = "category_id"; colComponentId.DataPropertyName = "component_id"; colPartNumber.DataPropertyName = "part_number"; colDescription.DataPropertyName = "description"; colPackage.DataPropertyName = "package"; colManufacturerId.DataPropertyName = "manufacturer_id"; colLifecycleId.DataPropertyName = "lifecycle_id"; comboColManufacturer.DataPropertyName = "manufacturer"; comboColLifecycle.DataPropertyName = "lifecycle";
数据填充代码
string query = @"SELECT cat.name AS category, cat.id AS category_id, cpmf.component_id, comp.part_number, comp.description, comp.package, cpmf.manufacturer_id, comp.lifecycle_status_id AS lifecycle_id, man.name AS manufacturer, lfs.name AS lifecycle FROM components AS comp INNER JOIN component_manufacturers AS cpmf ON comp.id = cpmf.component_id INNER JOIN manufacturers AS man ON cpmf.manufacturer_id = man.id INNER JOIN lifecycle_status AS lfs ON comp.lifecycle_status_id = lfs.id INNER JOIN categories AS cat ON comp.category_id = cat.id WHERE 1"; dgProducts.DataSource = Functions.MakeQuery(query); comboColManufacturer.DataSource = dt.AsEnumerable().Select(r => r.Field<string>("manufacturer")).ToList(); comboColLifecycle.DataSource = dt.AsEnumerable().Select(r => r.Field<string>("lifecycle")).ToList(); //Populate data grids dgProducts.Columns.AddRange(colCategory, colCategoryId, colComponentId, colPartNumber, colDescription, colPackage, colManufacturerId, colLifecycleId, comboColManufacturer, comboColLifecycle);
解决方案
通过监听DataGridView的EditingControlShowing事件,在ComboBox控件显示时为其绑定点击事件,触发整行选中操作,具体实现如下:
- 在窗体初始化阶段绑定
EditingControlShowing事件:
dgProducts.EditingControlShowing += dgProducts_EditingControlShowing;
- 实现事件处理逻辑:
private void dgProducts_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { // 判断当前编辑控件是否为ComboBox if (e.Control is ComboBox comboBox) { // 移除已存在的点击事件,避免重复绑定导致多次触发 comboBox.Click -= ComboBox_Click; // 绑定新的点击事件 comboBox.Click += ComboBox_Click; // 可选:如果需要点击下拉箭头时也选中整行,绑定DropDown事件 comboBox.DropDown -= ComboBox_DropDown; comboBox.DropDown += ComboBox_DropDown; } } private void ComboBox_Click(object sender, EventArgs e) { SelectCurrentRow(); } private void ComboBox_DropDown(object sender, EventArgs e) { SelectCurrentRow(); } // 封装整行选中的通用逻辑 private void SelectCurrentRow() { if (dgProducts.CurrentCell != null) { int rowIndex = dgProducts.CurrentCell.RowIndex; dgProducts.Rows[rowIndex].Selected = true; } }
说明
- 移除重复事件绑定是为了避免每次进入编辑模式时重复添加事件,导致同一操作多次触发。
- 封装
SelectCurrentRow方法可以统一整行选中的逻辑,便于维护和扩展。
内容的提问来源于stack exchange,提问作者Alex Alexuz
相关产品推荐
相关产品推荐

