C# WinForm:DataGridView中DateTimePicker按ESC退出编辑模式
解决DataGridView嵌入DateTimePicker按下ESC后无法退出编辑模式的问题
我来帮你搞定这个问题!你现在遇到的情况是:按下ESC键后,单元格值虽然恢复成了旧值,但DateTimePicker还卡在编辑状态,没法回到正常的视图模式。这是因为咱们之前只标记了取消编辑的状态,却没主动终止DataGridView的单元格编辑流程,也没重置DateTimePicker的显示状态。
咱们可以通过几个关键修改来解决这个问题,直接上修改后的完整代码,再给你拆解关键点:
public bool CellEditCanceled { get; set; } private DateTime oldDateValue; // 确保这个字段已经在类里定义好了 private void gvInstanceDetails_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { CellEditCanceled = false; if (gvInstanceDetails.Focused && gvInstanceDetails.CurrentCell.ColumnIndex == 5) { var cellRect = gvInstanceDetails.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); oDateTimePicker.Location = cellRect.Location; oDateTimePicker.Size = cellRect.Size; // 加这行让DateTimePicker完全贴合单元格,避免显示错位 oDateTimePicker.Visible = true; if (gvInstanceDetails.CurrentCell.Value != null) { oldDateValue = (DateTime)gvInstanceDetails.CurrentCell.Value; oDateTimePicker.Value = oldDateValue; } else { oDateTimePicker.Value = DateTime.Today; } } else { oDateTimePicker.Visible = false; } } private void gvInstanceDetails_CellEndEdit(object sender, DataGridViewCellEventArgs e) { if (gvInstanceDetails.Focused && gvInstanceDetails.CurrentCell.ColumnIndex == 5) { if (CellEditCanceled) { // 把单元格值恢复成旧值 gvInstanceDetails.CurrentCell.Value = oldDateValue; oDateTimePicker.Value = oldDateValue; } else { // 确认编辑,把DateTimePicker的新值保存到单元格 gvInstanceDetails.CurrentCell.Value = oDateTimePicker.Value; } // 不管编辑是取消还是确认,结束后都隐藏DateTimePicker oDateTimePicker.Visible = false; } } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { Keys key = keyData & Keys.KeyCode; if (gvInstanceDetails.CurrentCell != null && gvInstanceDetails.CurrentCell.IsInEditMode) { if (key == Keys.Escape) { CellEditCanceled = true; // 强制终止DataGridView的单元格编辑流程,触发CellEndEdit事件 gvInstanceDetails.CancelEdit(); // 立刻隐藏DateTimePicker,回到DataGridView的视图模式 oDateTimePicker.Visible = false; // 把焦点切回DataGridView,彻底退出DateTimePicker的编辑状态 gvInstanceDetails.Focus(); return true; // 标记这个按键已经被处理,避免系统默认的后续操作 } } return base.ProcessCmdKey(ref msg, keyData); }
核心修改点说明:
- 主动终止编辑流程:在ESC按键处理中调用
gvInstanceDetails.CancelEdit(),直接结束DataGridView的单元格编辑,触发CellEndEdit事件,让整个编辑流程完整收尾。 - 立即隐藏DateTimePicker:按下ESC后马上设置
oDateTimePicker.Visible = false,让控件从界面上消失,直接回到DataGridView的默认视图状态。 - 切回焦点到DataGridView:用
gvInstanceDetails.Focus()确保焦点离开DateTimePicker,彻底退出它的编辑状态。 - 适配控件大小:在
CellBeginEdit里添加oDateTimePicker.Size = cellRect.Size,让DateTimePicker完全贴合单元格,避免显示错位问题。 - 统一结束状态:不管编辑是取消还是确认,在
CellEndEdit最后都隐藏DateTimePicker,保证界面状态一致。
这样改完之后,按下ESC键时,不仅会恢复单元格的旧值,还会立刻退出DateTimePicker的编辑模式,回到DataGridView的正常视图状态啦!
内容的提问来源于stack exchange,提问作者Sakti Behera
相关产品推荐
相关产品推荐

