在 WinForms 開發中,DataGridView 是常用的數據展示控件。如何安全地判斷指定行列單元格是否存在並修改其值,是基礎且關鍵的操作。
DataGridView 的行集合 Rows 和儲存格集合 Cells 都是**零基索引**集合。判斷存在性本質是檢查索引是否在有效範圍內:
rowIndex 有效範圍:0 <= rowIndex < Rows.CountcolIndex 有效範圍:0 <= colIndex < Columns.Countpublic void SafeSetCellValue(DataGridView grid, int rowIndex, int colIndex, object value)
{
// 1. 空值防護
if (grid == null) throw new ArgumentNullException(nameof(grid));
// 2. 行索引檢查
if (rowIndex < 0 || rowIndex >= grid.Rows.Count)
{
MessageBox.Show($"行索引 {rowIndex} 超出範圍 (0-{grid.Rows.Count - 1})");
return;
}
// 3. 列索引檢查
if (colIndex < 0 || colIndex >= grid.Columns.Count)
{
MessageBox.Show($"列索引 {colIndex} 超出範圍 (0-{grid.Columns.Count - 1})");
return;
}
// 4. 獲取行並檢查 Cells 集合(極少數情況行未初始化 Cells)
DataGridViewRow row = grid.Rows[rowIndex];
if (row.Cells.Count <= colIndex) // 理論上不會發生,除非手動移除 Cells
{
MessageBox.Show($"第 {rowIndex} 行缺少第 {colIndex} 列單元格");
return;
}
// 5. 安全修改值
row.Cells[colIndex].Value = value;
// 6. 可選:強制重繪該單元格
grid.InvalidateCell(colIndex, rowIndex);
}
// 正確順序:先新增行,再修改
int newRowIndex = dataGridView1.Rows.Add(); // 返回新行索引
dataGridView1.Rows[newRowIndex].Cells["ColumnName"].Value = "新數據";
若 VirtualMode = true,單元格值由 CellValueNeeded 事件提供,**不能直接設置 Value 屬性**,需更新底層數據源並在事件中返回新值。
// 修改前檢查
if (dataGridView1.Columns[colIndex].ReadOnly ||
dataGridView1.Rows[rowIndex].Cells[colIndex].ReadOnly)
{
// 暫時取消唯讀
dataGridView1.Rows[rowIndex].Cells[colIndex].ReadOnly = false;
dataGridView1.Rows[rowIndex].Cells[colIndex].Value = value;
dataGridView1.Rows[rowIndex].Cells[colIndex].ReadOnly = true; // 恢復
}
最佳回答建議:「自己用代碼填充表格,別用綁定的方法」
綁定模式 (DataSource) 下修改單元格值實際是修改底層數據源物件屬性。若需直接控制單元格,**建議使用非綁定模式**:手動 Rows.Add()、Cells[].Value = ...,邏輯更清晰可控。
public static class DataGridViewExtensions
{
public static bool TrySetValue(this DataGridView grid, int row, int col, object value)
{
if (grid == null || row < 0 || row >= grid.Rows.Count || col < 0 || col >= grid.Columns.Count)
return false;
grid.Rows[row].Cells[col].Value = value;
return true;
}
public static T GetValue(this DataGridView grid, int row, int col, T defaultValue = default)
{
if (grid == null || row < 0 || row >= grid.Rows.Count || col < 0 || col >= grid.Columns.Count)
return defaultValue;
var val = grid.Rows[row].Cells[col].Value;
return val is T ? (T)val : defaultValue;
}
}
// 使用
dataGridView1.TrySetValue(1, 1, "新值");
string val = dataGridView1.GetValue(1, 1, "預設值");
總結:判斷單元格存在性核心是**索引邊界檢查**。封裝擴展方法可大幅簡化業務代碼,提高健壯性。非綁定模式下直接操作 Cells[].Value 最直觀;綁定模式請操作底層數據源。