You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:44:36