首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# DataGridView 單元格編輯驗證:CellValidating 事件完美實現取消編輯

     編輯:程式設計綜合問答

問題背景

需求:用戶編輯單元格結束時驗證數據,不合法則取消編輯、保持原值、提示錯誤。CellEndEdit 無 Cancel 屬性,無法直接阻止提交。

正確事件:CellValidating

private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
    // 1. 僅驗證特定列
    if (e.ColumnIndex != targetColumnIndex) return;

    // 2. 獲取用戶輸入值
    string input = e.FormattedValue?.ToString()?.Trim();

    // 3. 業務驗證邏輯
    if (!IsValid(input)) {
        // 4. 關鍵:取消編輯
        e.Cancel = true;

        // 5. 用戶提示(非模態,避免阻塞 UI 線程)
        this.BeginInvoke((Action)(() => {
            MessageBox.Show("輸入格式不正確,請重新輸入", "驗證失敗",
                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }));
    }
}

關鍵點解析

  • e.Cancel = true:通知 DataGridView 取消本次編輯,單元格恢復原值,焦點保留在該單元格。
  • e.FormattedValue:獲取用戶當前編輯控件中的顯示文本,而非底層數據源值。
  • BeginInvoke:彈窗必須異步執行,否則會干擾編輯控件的焦點狀態導致異常。

輔助:行級驗證 RowValidating

若需跨列聯動驗證(如開始時間 < 結束時間),使用 RowValidating 同樣設置 e.Cancel = true。

常見坑

  • 在 CellValidating 中直接修改 dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value 無效,因數據源尚未更新。
  • 若 DataGridView.DataSource 綁定 BindingList,驗證失敗後實體對象屬性不會被修改,安全。
  • 虛擬模式 (VirtualMode = true) 下需在 CellValuePushed 中驗證並拋異常回滾。

最佳實踐封裝

public static class DataGridViewExtensions {
    public static void AddCellValidation(this DataGridView dgv, int colIndex, Func validator, string errorMsg) {
        dgv.CellValidating += (s, e) => {
            if (e.ColumnIndex == colIndex && !validator(e.FormattedValue?.ToString())) {
                e.Cancel = true;
                dgv.BeginInvoke((Action)(() => MessageBox.Show(errorMsg)));
            }
        };
    }
}

// 使用
dataGridView1.AddCellValidation(2, v => decimal.TryParse(v, out _), "請輸入有效金額");
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved