Design Patterns 初學與參考連結

這次開始學習Design Patterns,參考的書籍是這一本:
設計模式的解析與活用
(Design Patterns Explained: A New Perspective on Object-Oriented Design)

此書介紹12個常用的設計模式
除了閱讀書本中介紹的例子
我也搭配其他作者的網頁介紹一起服用
參考連結如下

 

廣告

[C#] DataGridView 應用(五) – ComboBoxCell置換技巧

上一篇:[C#] DataGridView 應用(四) – DataGridViewCell
介紹了DataGridViewCell的幾種類型與使用方法
這篇將示範Cell置換的技巧


在第三篇中 ([C#] DataGridView 應用(三) – 修改資料、條件設定)
我們學到修改資料的方法
如下圖,我們可以手動輸入ContactName的內容
但若是我們已經有ContactName的選項清單
希望使用者不要手動輸入
就可以利用ComboBoxCell
把修改資料的方式,改為用清單選擇的方式
2016-5-11 下午 05-50-48


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

2016-7-7 上午 10-53-41

記得在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編輯
}

呈現的效果如下圖

2016-7-7 上午 11-19-22.png


記得在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 (取消修改)

記得多模擬一些使用情境
撰寫防止錯誤的方法唷!

[C#] DataGridView 應用(四) – DataGridViewCell

上一篇[C#] DataGridView 應用(三) – 修改資料、條件設定
介紹了資料修改與資料驗證的方法
這篇將介紹一下DataGridViewCell


首先可以查看MSDN的DataGridViewCell 類別
繼承它的類別有:

  • DataGridViewButtonCell
  • DataGridViewCheckBoxCell
  • DataGridViewComboBoxCell
  • DataGridViewHeaderCell
  • DataGridViewImageCell
  • DataGridViewLinkCell
  • DataGridViewTextBoxCell

這邊我實作兩種使用方法
首先是可以直接新增特定類型的Column
底下的Cell就會直接預設為目標類型
如下段Code及圖片

dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn());
dataGridView1.Columns.Add(new DataGridViewComboBoxColumn());
dataGridView1.Columns.Add(new DataGridViewButtonColumn());
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());

dataGridView1.Rows.Add(10);

for (int i = 0; i < 10; i++)
{
  dataGridView1.Rows[i].Cells[3].Value = "Text";
}

2016-7-6 下午 04-33-11


若是想在同一個Column,使用不同類型的Cell
只要直接做置換的動作,並給予預設值即可
示範結果如下

dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
            
DataGridViewCheckBoxCell chkCell = new DataGridViewCheckBoxCell();
chkCell.Value = false;
dataGridView1.Rows[2].Cells[4] = chkCell;

DataGridViewComboBoxCell cbCell = new DataGridViewComboBoxCell();
dataGridView1.Rows[4].Cells[4] = cbCell;

DataGridViewButtonCell btnCell = new DataGridViewButtonCell();
dataGridView1.Rows[6].Cells[4] = btnCell;

2016-7-6 下午 04-50-56.png

完成!
下一篇:[C#] DataGridView 應用(五) – ComboBoxCell置換技巧