Datagridview同一列单元格有textbox和combox(使用EditingControlShowing事件动态覆盖编辑控件)
使用EditingControlShowing事件动态覆盖编辑控件
完整代码
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 11 namespace Demo1 12 { 13 public partial class Form2 : Form 14 { 15 public Form2() 16 { 17 InitializeComponent(); 18 } 19 20 private void Form2_Load(object sender, EventArgs e) 21 { 22 //dataGridView1.AutoGenerateColumns = false; 23 //dataGridView1.DataSource = null; 24 myDatas.Add(myData); 25 myDatas.Add(myData1); 26 dataGridView1.DataSource = myDatas; 27 } 28 List<MyData> myDatas = new List<MyData>(); 29 MyData myData = new MyData(); 30 MyData myData1 = new MyData(); 31 32 private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 33 { 34 // 判断是否是需要特殊处理的列和行 35 36 int ColumnIndex= dataGridView1.CurrentCell.ColumnIndex; 37 int RowIndex= dataGridView1.CurrentCell.RowIndex; 38 39 Console.WriteLine($"ColumnIndex={ColumnIndex},RowIndex={RowIndex}"); 40 if (ColumnIndex == 1 && RowIndex == 1) 41 { 42 43 // 关键1:移除之前可能添加的事件处理程序,防止重复订阅 44 if (currentOverlayControl is ComboBox previousCombo) 45 { 46 previousCombo.SelectedIndexChanged -= OverlayComboBox_SelectedIndexChanged; 47 } 48 if (currentOverlayControl is TextBox previousText) 49 { 50 previousText.TextChanged -= OverlayTextBox_TextChanged; 51 } 52 53 // 移除当前可能存在的覆盖控件 54 if (currentOverlayControl != null) 55 { 56 dataGridView1.Controls.Remove(currentOverlayControl); 57 currentOverlayControl.Dispose(); 58 currentOverlayControl = null; 59 } 60 61 // 获取默认的编辑控件(通常是一个TextBox)及其位置 62 Control defaultControl = e.Control; 63 Rectangle cellRect = dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex, false); 64 65 // 关键2:根据“类型”列的值决定创建哪种覆盖控件 66 string currentType = dataGridView1.CurrentCell.Value?.ToString(); 67 //bool isCategoryType = currentType == "分类"; 68 69 if (true) 70 { 71 // 创建并配置覆盖用的ComboBox 72 ComboBox overlayCombo = new ComboBox(); 73 overlayCombo.DropDownStyle = ComboBoxStyle.DropDownList; // 设置为下拉列表 74 overlayCombo.Items.Add("选项A"); // 设置数据源 75 overlayCombo.Items.Add("选项B"); // 设置数据源 76 overlayCombo.Items.Add("选项C"); // 设置数据源 77 overlayCombo.Size = new Size(cellRect.Width, overlayCombo.Height); 78 79 // 设置初始值为当前单元格的值 80 overlayCombo.SelectedItem = dataGridView1.CurrentCell.Value; 81 82 // 关键3:将ComboBox添加到DataGridView的控件集合中,并定位到当前单元格 83 overlayCombo.Location = new Point(cellRect.Left, cellRect.Top); 84 dataGridView1.Controls.Add(overlayCombo); 85 86 // 订阅ComboBox的值改变事件 87 overlayCombo.SelectedIndexChanged += OverlayComboBox_SelectedIndexChanged; 88 89 // 将焦点和选择项设置给覆盖控件 90 overlayCombo.BringToFront(); 91 overlayCombo.Focus(); 92 currentOverlayControl = overlayCombo; 93 } 94 else 95 { 96 // 创建并配置覆盖用的TextBox 97 TextBox overlayText = new TextBox(); 98 overlayText.Size = new Size(cellRect.Width, cellRect.Height); 99 overlayText.Text = dataGridView1.CurrentCell.Value?.ToString() ?? ""; 100 101 overlayText.Location = new Point(cellRect.Left, cellRect.Top); 102 dataGridView1.Controls.Add(overlayText); 103 104 // 订阅TextBox的文本改变事件 105 overlayText.TextChanged += OverlayTextBox_TextChanged; 106 107 overlayText.BringToFront(); 108 overlayText.Focus(); 109 currentOverlayControl = overlayText; 110 } 111 112 // 隐藏默认的编辑控件 113 defaultControl.Visible = false; 114 115 } 116 } 117 // 当覆盖的ComboBox选项改变时,实时更新单元格的值 118 private void OverlayComboBox_SelectedIndexChanged(object sender, EventArgs e) 119 { 120 if (sender is ComboBox combo && dataGridView1.CurrentCell != null) 121 { 122 dataGridView1.CurrentCell.Value = combo.SelectedItem; 123 } 124 } 125 126 // 当覆盖的TextBox文本改变时,实时更新单元格的值 127 private void OverlayTextBox_TextChanged(object sender, EventArgs e) 128 { 129 if (sender is TextBox textBox && dataGridView1.CurrentCell != null) 130 { 131 dataGridView1.CurrentCell.Value = textBox.Text; 132 } 133 } 134 // 声明一个变量来跟踪当前覆盖的控件,避免重复创建 135 private Control currentOverlayControl = null; 136 // 清理覆盖控件的方法 137 private void CleanupOverlayControl() 138 { 139 if (currentOverlayControl != null) 140 { 141 // 移除事件订阅 142 if (currentOverlayControl is ComboBox combo) 143 { 144 combo.SelectedIndexChanged -= OverlayComboBox_SelectedIndexChanged; 145 } 146 else if (currentOverlayControl is TextBox textBox) 147 { 148 textBox.TextChanged -= OverlayTextBox_TextChanged; 149 } 150 151 // 从控件集合中移除并释放资源 152 dataGridView1.Controls.Remove(currentOverlayControl); 153 currentOverlayControl.Dispose(); 154 currentOverlayControl = null; 155 } 156 157 // 确保默认的编辑控件再次可见 158 if (dataGridView1.EditingControl != null) 159 { 160 dataGridView1.EditingControl.Visible = true; 161 } 162 } 163 164 private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 165 { 166 CleanupOverlayControl(); 167 } 168 169 private void button1_Click(object sender, EventArgs e) 170 { 171 string fstr = myDatas[1].Name; 172 MessageBox.Show(fstr); 173 } 174 } 175 public class MyData 176 { 177 public int Age { get; set; } = 110; 178 public string Name { get; set; }= "张三"; 179 180 181 } 182 }

浙公网安备 33010602011771号