上一篇:[C#] DataGridView 應用(四) – DataGridViewCell
介紹了DataGridViewCell的幾種類型與使用方法
這篇將示範Cell置換的技巧
在第三篇中 ([C#] DataGridView 應用(三) – 修改資料、條件設定)
我們學到修改資料的方法
如下圖,我們可以手動輸入ContactName的內容
但若是我們已經有ContactName的選項清單
希望使用者不要手動輸入
就可以利用ComboBoxCell
把修改資料的方式,改為用清單選擇的方式

首先加入「修改」到右鍵選單,如下圖
(可參考:[C#] DataGridView 應用(二) – 右鍵選單、新增資料)

記得在Mouse Down的事件中
利用HitTestInfo來捕捉滑鼠所點擊的位置
這邊我用兩個變數,儲存要編輯的Row Index及Column Index
int editRow;
int editCol;
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)//按下右鍵
{
//捕捉使用者點擊的Row及Column
DataGridView.HitTestInfo hti = dataGridView1.HitTest(e.X, e.Y);
editRow = hti.RowIndex;
editCol = hti.ColumnIndex;
//顯示右鍵選單
menu.Show(dataGridView1, new Point(e.X, e.Y));
}
}
然後在右鍵選單的「修改」事件
把ComboBox清單,置換到要修改的格子中
讓使用者可以直接點選
string strBeforeEdit;
bool bComboBoxEdit = false;
private void miEdit_Click(object sender, System.EventArgs e)
{
DataGridViewCell editCell = dataGridView1.Rows[editRow].Cells[editCol];//欲修改的格子
strBeforeEdit = editCell.Value.ToString();//紀錄修改前的值
//建立ComboBox的清單
DataGridViewComboBoxCell cbCell = new DataGridViewComboBoxCell();
cbCell.Items.Add("Yang Wang");
cbCell.Items.Add("Pedro Afonso");
cbCell.Items.Add("Sven Ottlieb");
cbCell.Items.Add("Roland Mendel");
cbCell.Items.Add("");
cbCell.Items.Add("Cancel Edit");//讓使用者可以取消編輯
//置換格子
dataGridView1.Rows[editRow].Cells[editCol] = cbCell;
bComboBoxEdit = true;//紀錄為ComboBox編輯
}
呈現的效果如下圖

記得在CellEndEdit的前段寫入bComboBoxEdit的判斷
ComboBox的點擊事件要另外做
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (bComboBoxEdit == true)
return;
然後修改DataGridView的EditingControlShowing事件
用來幫我們的ComboBox關聯SelectedIndexChanged事件
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
ComboBox comboBox = e.Control as ComboBox;
comboBox.SelectedIndexChanged -= ComboBox_SelectedIndexChanged;
comboBox.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
}
}
最後編寫SelectedIndexChanged事件
一樣使用Entity Framework修改資料庫的資料
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
//取得編輯中的格子內容
ComboBox cb = (ComboBox)sender;
string text = cb.Text;
if (text == "Cancel Edit")//取消
{
//復原編輯前狀態
DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
cell.Value = strBeforeEdit;
dataGridView1.Rows[editRow].Cells[editCol] = cell;
//後續也不需實際進資料庫修改
return;
}
else
{
//進資料庫修改
//取得第一格的CustomerID
string customerID = (dataGridView1.Rows[editRow].Cells[0].Value ?? "").ToString();
//從資料庫根據ID取得目標Customer
Customers cus = ef.Customers.Where(x => x.CustomerID == customerID).First();
cus.ContactName = text;
ef.Entry(cus).State = System.Data.Entity.EntityState.Modified;
ef.SaveChanges();
MessageBox.Show("修改成功");
//將ComboBox回復為TextCell
DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
cell.Value = text;
dataGridView1.Rows[editRow].Cells[editCol] = cell;
}
}
到這邊就把功能完成了
不過多玩幾次就可以發現有些小bug
例如:點擊修改→取得ComboBox→未實際點選,又修改別的儲存格
這時就要記得把上一個ComboBox變回TextCell (取消修改)
記得多模擬一些使用情境
撰寫防止錯誤的方法唷!