【C#】避免 DataGridView 排序導致取錯行:請用 DataBoundItem 而非 Rows[e.RowIndex]
Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
If you wish to repost this article, please include the original source link and this copyright notice.
Source link: https://v2know.com/article/1157
在使用 WinForms 的 DataGridView
搭配 DataTable
或其他繫結資料來源時,你是否曾遇過以下狀況?
使用者編輯某一列的資料,但實際讀取或更新的卻是另一筆記錄?
這種問題多半發生在你直接用 dgv.Rows[e.RowIndex]
存取儲存格資料,而此時 DataGridView
剛好啟用了排序或過濾功能。本文將說明這個問題的成因,並提供正確的寫法。
❌ 錯誤寫法:Rows[e.RowIndex]
我們常見的寫法如下:
object keyValue = dgv.Rows[e.RowIndex].Cells[meta.KeyColumn].Value;
這段程式碼看似沒問題,但如果你的 DataGridView
是透過 DataSource
綁定了 DataTable
,一旦啟用了排序(點擊欄位標題排序)或過濾功能,那麼 Rows[e.RowIndex]
的行就不再對應於 DataTable
中的原始資料順序。
換句話說,你以為你正在取用第 N 筆資料,但實際上拿到的可能是另一筆。
✅ 正確寫法:使用 DataBoundItem
解法其實很簡單:繞過 DataGridView 的顯示順序,直接存取資料來源本體。
var row = ((DataRowView)dgv.Rows[e.RowIndex].DataBoundItem).Row;
object keyValue = row[meta.KeyColumn];
這段寫法中,我們透過 DataBoundItem
取得資料列的 DataRowView
,再從中拿到真實的 DataRow
。這樣可以確保你抓到的資料始終是原始資料來源中的正確一筆,無論使用者如何排序或篩選畫面。
🧪 測試方式建議
-
對
DataGridView
綁定一個DataTable
。 -
啟用
AllowUserToOrderColumns = true
。 -
實作
CellValueChanged
或CellEndEdit
。 -
測試排序前後,所取得的
row["主鍵"]
是否仍一致。
📝 小結
寫法 | 是否正確 | 說明 |
---|---|---|
dgv.Rows[e.RowIndex].Cells[...] |
❌ 錯誤 | 容易因排序導致取錯行 |
((DataRowView)dgv.Rows[e.RowIndex].DataBoundItem).Row |
✅ 正確 | 可準確取得原始資料行 |
在 WinForms 資料繫結的世界裡,DataBoundItem
是你和資料來源間的「真實通道」。別再依賴 DataGridView 排序後的表面行順序,否則 debug 時你可能會陷入一場無止盡的謎團。
This article was last edited at