WinForms+DataGridView:按下Enter时获取更新单元格值的实现问题
Hey there! I see you're getting started with WinForms and C# using DataGridView, and you need to trigger validation when the user presses Enter after editing Column2. Let's break down why your previous events didn't work, then walk through a solid, working solution.
Why your existing events weren't the right fit
CellEnter/CellClick: These fire when the user selects a cell, not when they finish entering and confirming a value. They don't capture the moment input is finalized.CellValueChanged: This triggers as soon as the cell's value changes (even mid-typing), not when the user presses Enter to lock in their edit. That's why you weren't getting the behavior you needed.
The right approach: Use the KeyDown event
We'll hook into the DataGridView's KeyDown event to detect when the Enter key is pressed, then validate the input against Column3 and Column4 values. Here's how to implement it step by step:
Register the KeyDown event
You can do this via the Visual Studio designer (select your DataGridView, go to the Properties window → Events tab → double-clickKeyDown), or add this line to your form's constructor:dataGridView1.KeyDown += DataGridView1_KeyDown;Implement the event handler
Add this method to your form's code. It checks if we're in Column2, validates the input, and shows the appropriate message:private void DataGridView1_KeyDown(object sender, KeyEventArgs e) { // Check if the Enter key was pressed if (e.KeyCode == Keys.Enter) { var currentCell = dataGridView1.CurrentCell; if (currentCell == null) return; // Only process Column2 (index 1) and skip the header row if (currentCell.ColumnIndex == 1 && currentCell.RowIndex >= 0) { // Finalize editing to ensure the cell's updated value is saved dataGridView1.EndEdit(); var currentRow = dataGridView1.Rows[currentCell.RowIndex]; // Pull values from Column2, Column3, and Column4 string inputStr = currentRow.Cells[1].Value?.ToString().Trim(); string minRangeStr = currentRow.Cells[2].Value?.ToString().Trim(); string maxRangeStr = currentRow.Cells[3].Value?.ToString().Trim(); // Validate that all values are valid numbers (avoid crashes from bad input) if (decimal.TryParse(inputStr, out decimal inputValue) && decimal.TryParse(minRangeStr, out decimal minValue) && decimal.TryParse(maxRangeStr, out decimal maxValue)) { // Check if input falls within the range if (inputValue >= minValue && inputValue <= maxValue) { MessageBox.Show("值在范围内", "验证结果"); } else { MessageBox.Show("值不正确", "验证结果"); } } else { MessageBox.Show("请输入有效的数值", "输入错误"); } // Optional: Stop Enter from moving to the next cell e.Handled = true; } } }
Key details to note
EndEdit(): This ensures the cell's edited value is saved to the DataGridView before we read it—critical because without it, you might still get the old, pre-edit value.- Numeric parsing: We use
decimal.TryParseto handle all numeric types (int, float, etc.) and avoid crashes if the user enters non-numeric text. - Row index check: Makes sure we don't try to process the header row (which has a row index of -1).
e.Handled = true: Optional, but this stops the default Enter behavior (moving to the next cell) if you want to keep focus on the current cell after validation.
Bonus: Lock down read-only columns
Double-check that your non-editable columns are set to read-only (either in the designer or code):
// Set Columns 0, 2, 3, 4 to read-only dataGridView1.Columns[0].ReadOnly = true; dataGridView1.Columns[2].ReadOnly = true; dataGridView1.Columns[3].ReadOnly = true; dataGridView1.Columns[4].ReadOnly = true; // Confirm Column2 is editable (default is false for ReadOnly, but explicit is safer) dataGridView1.Columns[1].ReadOnly = false;
This setup will give you exactly the behavior you want: when the user presses Enter after editing Column2, the value is validated against the range in Column3 and Column4, with the correct message popping up immediately.
内容的提问来源于stack exchange,提问作者Margarita Gonzalez

