DataGridView 是一種表格樣式的控制項,專門用來顯示資料用的。 不論有沒有基礎資料來源,您都可以使用 DataGridView 控制項來顯示資料。 若沒有指定資料來源,你可以先建立包含資料的資料行和資料列,再將它們加入 DataGridView 。 若使用資料來源,你可以設定 DataSource 和 DataMember 屬性,讓 DataGridView 與資料建立繫結,就可以自動填入資料。
DataGridView 控制項架構
構成 DataGridView 控制項的相關類別,都包含在 System.Windows.Forms 命名空間中,而且全部都以 "DataGridView" 前置詞命名。 DataGridView 控制項是由兩個主要物件所組成:儲存格(Cells)和群組列(Bands),這些物件都是由 DataGridViewElement 類別衍生出來的。 下圖為 DataGridViewElement 類別的物件模型:

所以說,最主要用來與 DataGridView 控制項互動的類別,就是是底下三個:
儲存格
儲存格是最基本的互動單位,每一個儲存格都必須是一個 DataGridViewCell 型別,但是 DataGridViewCell 是一個抽象基底類別,所以實際的儲存格型別都是從它衍生出來的。
下列清單是 DataGridViewCell 的衍生類別:
- DataGridViewButtonCell
- DataGridViewTextBoxCell
- DataGridViewCheckBoxCell
- DataGridViewComboBoxCell
- DataGridViewImageCell
- DataGridViewLinkCell
- DataGridViewHeaderCell
- DataGridViewRowHeaderCell
- DataGridViewColumnHeaderCell
- DataGridViewTopLeftHeaderCell
- 自訂型別的儲存格
儲存格樣式
你可以透過以下屬性來設定儲存格的樣式:
- DefaultCellStyle
- ColumnHeadersDefaultCellStyle
- CellBorderStyle
- GridColor
//若要讓資料列和資料行行首使用自訂的視覺化樣式
//必須停止應用程式啟用的視覺化樣式.
dgView2.EnableHeadersVisualStyles = false;
//設定儲存格樣式,
//只有在使用單一框線時,才可以將 GridColor 屬性設定為任何色彩;
//若使用其他類型的框線,則是由作業系統指定色彩。
dgView2.CellBorderStyle = DataGridViewCellBorderStyle.Single;
dgView2.GridColor = Color.Blue ;
//定義一個樣式
DataGridViewCellStyle headStyle = new DataGridViewCellStyle();
headStyle.BackColor = Color.Yellow;
headStyle.ForeColor = Color.Red;
headStyle.Font = new Font("Verdana", 12, FontStyle.Bold);
//定義一個樣式
DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
cellStyle.Font = new Font("Ariel", 12, FontStyle.Regular);
//分配樣式給 ColumnHeader
dgView2.ColumnHeadersDefaultCellStyle = headStyle;
//分配樣式給 Columns
dgView2.Columns.Add("col1", "col1_head");
dgView2.Columns[0].DefaultCellStyle = cellStyle;
群組列
DataGridViewColumn 和 DataGridViewRow 都算是一種群組列(Band)結構,二者都是衍生自 DataGridViewBand 基底類別。
資料行
DataGridViewColumn 類別是用來代表 DataGridView 控制項中的資料行,它主要是用來控制 Grid 的外觀和行為,也就是和 UI 相關的設定。 例如欄位寛度或儲存格的樣式等。
下圖為 DataGridViewColumn 類別的物件模型:

下面程式碼,簡單示範如何加入一個資料行到 DataGridView 控制項中
//定義一個資料行的樣式
DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
cellStyle.BackColor = Color.Aqua;
cellStyle.Font = new Font("Verdana", 10, FontStyle.Bold);
//定義一個用來放置TextBox型別的資料行
DataGridViewCell Cell1 = new DataGridViewTextBoxCell();
DataGridViewColumn Column1 = new DataGridViewColumn(Cell1);
Column1.HeaderText = "Head1";
Column1.Name = "Column1";
//定義另一個用來放置ComboBox型別的資料行
DataGridViewComboBoxCell Cell2 = new DataGridViewComboBoxCell();
Cell2.Items.Add("111");
Cell2.Items.Add("222");
DataGridViewColumn Column2 = new DataGridViewColumn(Cell2);
Column2.HeaderText = "Head2";
Column2.Name = "Column2";
//在 DataGridView 中加入資料行
dgView2.Columns.Add(Column1);
dgView2.Columns["Column1"].DefaultCellStyle = cellStyle;
//在 DataGridView 中加入資料行
dgView2.Columns.Add(Column2);

由上面例子可以知道,要用什麼型別的欄位,就必須在 DataGridViewColumn 中裝載什麼型別的 DataGridViewCell 。 在 .NET 中,已經事先定義好下列幾個常用的儲存格型別,它們都是 DataGridViewColumn 的衍生類別:
- DataGridViewButtonColumn
- DataGridViewTextBoxColumn
- DataGridViewCheckBoxColumn
- DataGridViewComboBoxColumn
- DataGridViewImageColumn
- DataGridViewLinkColumn
你就可以直接使用這些衍生類別來建立資料行。
//定義一個 DataGridViewTextBoxColumn
DataGridViewTextBoxColumn Column3 = new DataGridViewTextBoxColumn();
Column3.HeaderText = "Head3";
Column3.Name = "Column3";
dgView2.Columns.Add(Column3);
//定義一個 DataGridViewCheckBoxColumn
DataGridViewCheckBoxColumn Column4 = new DataGridViewCheckBoxColumn();
Column4.HeaderText = "Head4";
Column4.Name = "Column4";
dgView2.Columns.Add(Column4);

資料列
如果說 DataGridViewColumn 是用來設定 DataGridView 的欄位型態,那麼 DataGridViewRow 則是用來表示要顯示到 DataGridView 上的資料欄位。 您可以使用 Rows 集合,存取 DataGridView 控制項的資料列。 另外,可以使用 SelectedRows 集合,存取選取的資料列。
DataGridViewRow row = dgv.Rows[index];
row.Cells[0].Value = trade.TradeNum;
row.Cells[1].Value = trade.TradeDate;
row.Cells[2].Value = trade.TradeType;
row.Cells[3].Value = trade.StockID;
row.Cells[4].Value = trade.StockName;
不使用繫結
若要使用 DataGridView 控制項來顯示資料,可分成三種模式:繫結、未繫結和虛擬。
未繫結模式適用於顯示少量的資料,由其對於靜態、唯讀的資料特別有用。 未繫結模式通常會藉由程式直接將資料填入控制項之中,
編輯資料行
如何加入資料行
構成 DataGridView 資料行的物件是 DataGridViewColumnCollection,它提供2個 Add 方法,可以用來加入資料行。
public virtual int Add(DataGridViewColumn dataGridViewColumn); public virtual int Add(string columnName, string headerText);
若要建立一個 DataGridViewColumn , 必需提供一個 DataGridViewCell 當做參數。 不過由於 DataGridViewCell 是一個抽象類別, 所以直接提供一個 DataGridViewCell 的衍生類別:
DataGridViewCell 的衍生類別
- DataGridViewButtonCell
- DataGridViewCheckBoxCell
- DataGridViewComboBoxCell
- DataGridViewImageCell
- DataGridViewLinkCell
- DataGridViewTextBoxCell
DataGridViewColumn 的衍生類別
與 DataGridViewCell 相對應的, DataGridViewColumn 也有下列幾個衍生類別。
- DataGridViewButtonColumn
- DataGridViewCheckBoxColumn
- DataGridViewComboBoxColumn
- DataGridViewImageColumn
- DataGridViewLinkColumn
- DataGridViewTextBoxColumn
加入一個 DataGridViewColumn
DataGridViewCell cell = new DataGridViewTextBoxCell(); // 注意: DataGridViewCell 是個 virutal class
DataGridViewColumn dgvCol = new DataGridViewColumn(cell);
col1.HeaderText = "col1";
col1.Name = "col1";
dgv.Columns.Add(dgvCol);
加入一個 DataGridViewColumn 的衍生類別
// Add DataGridViewTextBoxColumn
DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();
col2.HeaderText = "col2";
col2.Name = "col2";
dgv.Columns.Add(col2);
// Add DataGridViewComboBoxColumn
DataGridViewComboBoxColumn col4 = new DataGridViewComboBoxColumn();
col4.Items.Add("item1");
col4.Items.Add("item2");
col4.Items.Add("item3");
dgv.EditMode = DataGridViewEditMode.EditOnEnter; //DataGridViewEditMode 預設值是 EditOnKeystrokeOrF2 ,改成 EditOnEnter 才不用點二次,即可進入編輯。
col4.HeaderText = "col4";
col4.Name = "col4";
dgv.Columns.Add(col4);
直接加入資料行,並指定資料行行首文字
dgv.Columns.Add("col3", "col3_head");
資料行的屬性設定
資料行有多個屬性可以用來控制其外觀或表現行為,比較重要的有:
- ReadOnly:是否唯讀。
- Resizable:欄寛是否調整。
- AutoSizeMode:寬度要以何種方式自動調整。
- Frozen:設定某欄是否為凍結資料行。
DataGridViewColumn col2 = dgv.Columns[1];
col2.Name = "col2";
// 與[外觀]相關的屬性
col2.HeaderText = "col2_head";
col2.ToolTipText = "this is column 2";
col2.Visible = true;
// 設定 cell 樣式
DataGridViewCellStyle style = new DataGridViewCellStyle();
style.Font = new Font("細明體", 12);
style.BackColor = Color.Yellow;
col2.DefaultCellStyle = style;
// 與[行為]相關的屬性
col2.ReadOnly = false;
col2.Resizable = DataGridViewTriState.True;
col2.SortMode = DataGridViewColumnSortMode.Automatic;
// 與[配置]相關的屬性
dgv.Columns[2].Frozen = true; // 設定凍結資料行
dgv.Columns[0].Frozen = true; // 因為Columns[2]為凍結資料行,2以前都算凍結
col2.DividerWidth = 0; // 設定資料行分割線的寬度(凍結欄與非凍結欄的間距).
// 調整資料行寬度的方式
col2.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
// 指定欄寛
col2.Width = 200; // 欄位寛度
col2.MinimumWidth = 50; // 欄位最小寛度
col2.FillWeight = 200; // 輸入盒寛度,必須大於 0
//col.MaxInputLength = 5; // 最大可輸入字元數
dgv.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
//dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
//凍結資料行不可以使用 Fill 屬性值
編輯資料列
如何加入資料列
構成 DataGridView 資料列的物件是 DataGridViewRowCollection,它提供4個 Add 方法,可以用來加入資料列。
public virtual int Add(); public virtual int Add(DataGridViewRow dataGridViewRow); public virtual int Add(int count); public virtual int Add(params object[] values);
//1. 加入一個空白列
var index = dgv.Rows.Add();
dgv.Rows[index].Cells["Column1"].Value = "Column1";
dgv.Rows[index].Cells["Column1"].Value = "Column1";
//2. 加入一個 DataGridViewRow
DataGridViewRow row2 = (DataGridViewRow)dgv.Rows[0].Clone();
row2.Cells[0].Value = "row2_c1";
row2.Cells[1].Value = "row2_c2";
row2.Cells[2].Value = "row2_c3";
row2.Cells[3].Value = "item2";
dgv.Rows.Add(row2);
//3. 一次加入多列
dgv.Rows.Add(2);
//4. 加入一個指定內容的列
string[] row = new string[] { "row3_c1", "row3_c2", "row3_c3", "item3"};
dgv.Rows.Add(row);
dgv.Rows.Add("row4_c1", "row4_c2", "row4_c3", "item4");

使用資料繫結
使用繫結方式,主要就是希望不要人工進行管理,希望 DataGridView 可以自動管理資料。 當 DataGridView 繫結資料時,控制項便會自動完成推入(pushed)和提取(pulled)資料列的操作。
DataGridView 控制項支援標準的 Windows Form 資料繫結模型,因此它可以繫結至下列清單中所描述的類別執行個體。
- 實作 IList 介面的任何類別,例如一維陣列。
- 實作 IListSource 介面的任何類別,例如 DataTable 和 DataSet 類別。
- 實作 IBindingList 介面的任何類別,例如 BindingList<T> 類別。
- 實作 IBindingListView 介面的任何類別,例如 BindingSource 類別。
顯示資料
當 DataGridView 的 AutoGenerateColumns 屬性為 true 時,在資料來源中的每個資料行都會自動在 DataGridView 控制項中產生對應的資料行。 如果偏好建立自己的資料行,您可以將 AutoGenerateColumns 屬性設定為 false,然後透過 DataPropertyName 屬性來繫結每個資料行。
private SqlDataAdapter objAdapter;
private void GetData()
{
String strConn = ConfigurationManager.ConnectionStrings["EmpConnectionString"].ConnectionString;
SqlConnection objConn = new SqlConnection(strConn);
SqlCommand objCmd = new SqlCommand();
objCmd.Connection = objConn;
objCmd.CommandText = "SELECT ID, Name, Age FROM Emp";
DataTable dt = new DataTable();
objAdapter.SelectCommand = objCmd;
objAdapter.Fill(dt);
dataGridView1.DataSource = dt;
}
加入資料
當 DataGridView 繫結到資料來源時,你就不允許對它的 DataGridViewRow 或 DataGridViewColumn 進行操作。 若要變更 DataGridView 上的內容,你可以重新繫結到新的資料來源,或者對原始的資料來源做調整。
tblPhoto photo = new tblPhoto(); photo.Title = Path.GetFileNameWithoutExtension(file.FullName); photo.Summary = photo.Title; photo.FileName = file.FullName; photo.MD5 = md5; photo.SyncState = SyncStateEnum.New; bsDetail.Add(photo); //在 bind source 中加入一筆新的資料。
更新資料庫
要將資料更新回資料庫,可以直接叫用 DataAdapter 的 Update 方法,不過在叫用 Update 方法。 同樣的,在叫用前當然給先給定一個 UpdateCommand 物件,不過,如果要更改的對向是單一資料表,可以直接簡單的指定一個 SqlCommandBuilder 物件, SqlCommandBuilder 物件,它就會依據 SelectCommand 內容,自動產生更新命令,這樣叫用 Update 方法才會有效。 否則會產生錯誤訊息:「當傳遞擁有已修改資料列的 DataRow 集合時,更新需要有效的 UpdateCommand」。
private void btnUpdate_Click(object sender, EventArgs e)
{
//使用 CommandBuilder 來產生相對應的 Insert, Delete, Update SQL語法
var cmdBuilder = new SqlCommandBuilder();
cmdBuilder.DataAdapter = objAdapter;
objAdapter.Update(((DataTable)dataGridView1.DataSource));
}

作者已經移除這則留言。
回覆刪除請問 DataGridViewComboBoxColumn 資料透過 DataSource傳入 並新增至DataGridView上
回覆刪除可以指定Combobox的初值嗎? 謝謝