---
# System prepended metadata

title: C#Form DataGridView with database
tags: [DataGridView, C#]

---

# C#Form DataGridView with database
就是將DataGridView與database進行連結
順便教一下相關的創建等等
## 目錄
> [TOC]
## 加入database
加入它內建的資料庫
![螢幕擷取畫面 2025-01-20 142429](https://hackmd.io/_uploads/r1NB3woPkl.png)
![螢幕擷取畫面 2025-01-20 142448](https://hackmd.io/_uploads/rJwH3DoDJg.png)

點擊開啟Database
![螢幕擷取畫面 2025-01-20 142557](https://hackmd.io/_uploads/BJpihvjv1g.png)

於伺服器總管加入新的資料表
![螢幕擷取畫面 2025-01-20 142708](https://hackmd.io/_uploads/SkU1pDsvye.png)

然後就可以開始來設定資料類型與名稱
![螢幕擷取畫面 2025-01-20 143018](https://hackmd.io/_uploads/SJOYaPsvkg.png)
* 資料類型：
* int為數字
* nchar(5)為文字，括號後面就是可以輸入的資料長度

於下方程式碼更改程式名稱
更改姓名[Table]>>>[贊助金]
```
CREATE TABLE [dbo].[Table]  //這裡更改
(
	[Id] INT NOT NULL PRIMARY KEY, 
    [name] NCHAR(15) NULL, 
    [性別] NCHAR(10) NULL, 
    [贊助金額] NCHAR(25) NULL
)
```

按下左上角更新上傳設定結果>>更新資料庫結果
![螢幕擷取畫面 2025-01-20 143643](https://hackmd.io/_uploads/Skub1Osvyx.png)

於伺服器總管底下，按再重新整理一次，更新更改資料
![螢幕擷取畫面 2025-01-20 143823](https://hackmd.io/_uploads/HkLnydiDyg.png)

右鍵點擊資料庫名稱，顯示資料表資料，即可開始加入資料
資料都加入完畢後，點擊資料上方的更新鍵上傳即可
![螢幕擷取畫面 2025-01-20 144012](https://hackmd.io/_uploads/SkaHeOow1g.png)


## DataGridView
 這是一個存取資料所使用的，類似於以下


| 欄位 1 | 欄位 2 | 欄位 3 |
| -------- | -------- | -------- |
| 資料 1     | 資料 2     | 資料 3    |
|資料 4 |資料 5 |資料 6|

### 資料設定
 DataGridView的左上角就可以進行資料編輯
![螢幕擷取畫面 2025-01-20 141944](https://hackmd.io/_uploads/rJe7ovoDyg.png)
### 加入資料
```csharp=
dataGridView1.Rows.Add(資料1, 資料2, 資料3, 資料4);  //多列資料加入中間加上,
```
### 刪除
```csharp=
刪除指定索引的行：
dataGridView1.Rows.RemoveAt(rowIndex);

刪除選取的行：
dataGridView1.Rows.Remove(資料);
```
### 其他
```csharp=
dataGridView1.Rows.Clear();  //清空
int index = dataGridView1.CurrentRow.Index  //取得所選取是哪一行(第三行為2)
var value = dataGridView1.CurrentRow.Cells[0].Value;  // 讀取該行第 1 個欄位的值
var value = dataGridView1.CurrentRow.Cells["欄位名稱"].Value; // 透過欄位名稱讀取
dataGridView1.CurrentCell.Value   //讀取所選的那格資料
var selectedRow = dataGridView1.SelectedRows[0];//💡所有被選取的整列第一筆資料
    
dataGridView1.Columns.Add("ID", "ID");  // 新增名為 "ID" 的欄位
dataGridView1.Columns.Add("Name", "姓名");
dataGridView1.Columns.Add("Age", "年齡");

// 對時間欄位從早到晚排序（正排序）
dataGridView1.Sort(dataGridView1.Columns["ChargeStartDateTime"], ListSortDirection.Ascending);
// 對價格欄位從貴到便宜排序（倒排序）
dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Descending);

//資料快速載入，等載完再重新繪製
dataGridView1.SuspendLayout();
// while (...) 裡面的 Rows.Add(...)
dataGridView1.ResumeLayout();
```
### 各種類型欄位使用
也可以直接使用點擊的設定：
![螢幕擷取畫面 2025-06-15 134935](https://hackmd.io/_uploads/rJm6Lkhmxl.png)
✅ 範例：DataGridView 加入按鈕和圖片
```csharp=
// 新增 DataGridView 按鈕欄
DataGridViewButtonColumn btnColumn = new DataGridViewButtonColumn();
btnColumn.HeaderText = "操作";
btnColumn.Text = "Check";
btnColumn.UseColumnTextForButtonValue = true;
dataGridView1.Columns.Add(btnColumn);

// 新增 DataGridView 圖片欄
DataGridViewImageColumn colorCol = new DataGridViewImageColumn();
colorCol.Name = "PrimaryColorImage";  //程式碼搜索到的文字
colorCol.HeaderText = "主要顏色";  //顯示在資料上的文字
colorCol.ImageLayout = DataGridViewImageCellLayout.Zoom;
colorCol.Width = 60;
dataGridView2.Columns.Insert(5, colorCol); // 插入在你要的第6欄（位置自己調整）

// 新增 DataGridViewComboBoxColumn 選單欄
DataGridViewComboBoxColumn comboColumn = new DataGridViewComboBoxColumn();
comboColumn.HeaderText = "選項";
comboColumn.Items.AddRange("選項A", "選項B", "選項C");
comboColumn.DefaultCellStyle.NullValue = "選項A";  // 設定預設值為 "選項A"
dataGridView1.Columns.Add(comboColumn);

//快速設定法：
// 1. 品牌名稱 - 文字欄位
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn() { HeaderText = "品牌", Name = "colBrand" });
// 2. 品牌圖片 - 圖片欄位
dataGridView1.Columns.Add(new DataGridViewImageColumn() { HeaderText = "Logo", Name = "colImage", ImageLayout = DataGridViewImageCellLayout.Zoom });
// 3. 勾選欄 - CheckBox欄位
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn() { HeaderText = "啟用", Name = "colCheck" });
```
📌 多種欄位的資料加入：
```csharp=
Image toyotaImage = Image.FromFile("TOYOTA.jpg");
dataGridView1.Rows.Add(
    "TOYOTA",              // 品牌
    toyotaImage,           // Logo圖片
    true,                  // 勾選啟用
    "3",                   // ComboBox選項
    "https://www.toyota.com.tw/", // 網址
    "查看"                 // 按鈕文字（其實會被上面設定蓋掉）
);
```
📌 點擊事件處理：
```csharp=
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex] is DataGridViewButtonColumn)
    {
        MessageBox.Show($"你點擊了第 {e.RowIndex + 1} 行的按鈕！");
    }
}
-----------------------------------------------------------
//DataGridViewLinkColumn超(網頁)連結欄
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name == "Link")
    {
        string url = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
        System.Diagnostics.Process.Start(url);
    }
}
// 判斷是否是超連結欄點擊，方法二
    if (dataGridView1.Columns[e.ColumnIndex].Name == "colLink")
    {
        string url = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
        {
            FileName = url,
            UseShellExecute = true
        });
    }
```
----
📌 DataGridViewCheckBoxColumn的bool處理
```csharp=
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name == "Enable")
    {
        bool isChecked = (bool)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        MessageBox.Show(isChecked ? "啟用" : "未啟用");
    }
}
```
✅ 解決方法（取消自動新增列）：
只要在程式中把這個屬性設為 false 即可：
```csharp=
dataGridView1.AllowUserToAddRows = false;
```
你可以在 Form_Load 或 InitializeComponent 之後加上這一行，就不會自動新增新行了。

----
📦 3. DataGridViewComboBoxColumn（下拉選單欄）
➤ 設定欄位：
```csharp=
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.HeaderText = "選擇類型";
comboCol.Name = "Type";
comboCol.Items.AddRange("選項A", "選項B", "選項C");
dataGridView1.Columns.Add(comboCol);
```
➤ 點擊或選取反應：
```csharp=
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name == "Type")
    {
        string selected = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
        MessageBox.Show("你選了：" + selected);
    }
}
```
----
### 選取操作
```csharp=
if (dataGridView1.CurrentCell != null)
{
    int rowIndex = dataGridView1.CurrentCell.RowIndex;
    int colIndex = dataGridView1.CurrentCell.ColumnIndex;
    //int row = e.RowIndex;
    //int cell = e.ColumnIndex;
    
    // 取得目前儲存格的值
    var cellValue = dataGridView1.CurrentCell.Value?.ToString();
    MessageBox.Show($"第 {rowIndex} 行，第 {colIndex} 欄的值是: {cellValue}");

    // 取得整行資料
    DataGridViewRow row = dataGridView1.Rows[rowIndex];
    foreach (DataGridViewCell cell in row.Cells)
    {
        Console.WriteLine($"{dataGridView1.Columns[cell.ColumnIndex].HeaderText}: {cell.Value}");
    }
}
```
若要確保使用者只能選一整行，可以設定：
```csharp=
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
```
若你希望只能選一行而不是多行：
```csharp=
dataGridView1.MultiSelect = false;
```
### 列標頭1.2.3
✅ 方法一：使用 RowPostPaint 事件，在 **列標頭** 畫上編號（不會佔用欄位）
這種方式不需要額外加一欄，會在最左邊的灰色列標頭中顯示「1、2、3…」

* 點擊事件⚡RowPostPaint

📌 程式碼：
```csharp=
private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    using (SolidBrush b = new SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.ForeColor))
    {
        string rowNumber = (e.RowIndex + 1).ToString();
        e.Graphics.DrawString(rowNumber, e.InheritedRowStyle.Font, b,
        e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + 4);
    }
}
```
🔸 using (SolidBrush b = new SolidBrush(...))
這行是建立一支畫筆，SolidBrush 是用來畫文字或區塊顏色的物件。
* dataGridView1.RowHeadersDefaultCellStyle.ForeColor：
指的是列標頭預設的文字顏色，這樣畫出來的字會符合整體風格。

🔸 string rowNumber = (e.RowIndex + 1).ToString();
* e.RowIndex：這是目前要畫的列索引，從 0 開始。
*  (+ 1：讓它看起來從 1 開始編號（符合使用者習慣）
* .ToString()：把整數轉成文字，才能顯示在畫面上。

🔸 e.Graphics.DrawString(...)
這行的作用是「畫出一段文字」，這裡就是把編號畫在列頭。
參數說明：
* rowNumber：要畫的字（例如 "1", "2"...）
* e.InheritedRowStyle.Font：這列繼承來的字型（會跟你設計的字體一致）
* b：畫筆（用上面建立的顏色）
* e.RowBounds.Location.X + 15：
X 軸偏移一點點（讓字不要靠太左邊）
* e.RowBounds.Location.Y + 4：
Y 軸偏移一點點（讓字不要太上面）

----
✅ 方法二：新增一欄顯示自動編號（會佔一欄）
如果你想在第一個資料欄位就是「編號」，可以這樣做：

📌 範例程式：
```csharp=
// 加一欄作為編號欄
DataGridViewTextBoxColumn indexColumn = new DataGridViewTextBoxColumn();
indexColumn.Name = "編號";
indexColumn.HeaderText = "編號";
indexColumn.ReadOnly = true;
dataGridView1.Columns.Insert(0, indexColumn);

// 填入資料後產生編號
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
    dataGridView1.Rows[i].Cells["編號"].Value = (i + 1).ToString();
}
```
❗ 注意：
如果你是用 DataSource 綁定資料，則要在資料綁定之後執行這段迴圈（不然會無效或錯誤）。

🔁 若你想讓它「自動更新」編號（例如刪除一列後重新編號），可以放在事件中，如：
```csharp=
private void RefreshRowNumbers()
{
    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {
        dataGridView1.Rows[i].Cells["編號"].Value = (i + 1).ToString();
    }
}

private void dataGridView1_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
    RefreshRowNumbers();
}
```
## DataGridView with database
在 DataGridView左上角設定當中>>>點擊選擇資料來源>>>點擊底部的加入資料來源>>>接下來點選資料庫>>>一路按下一部即可>>>最後選擇自己的資料庫上傳
![螢幕擷取畫面 2025-01-20 144411](https://hackmd.io/_uploads/r1lUbdjDkl.png)

如果有加入成功在表單載入時應該會自動顯示
```csharp=
private void Form3_Load(object sender, EventArgs e)
{
    //TODO:這行程式碼會將資料載入'database1DataSet.贊助金'資料表 您可以視需要進行移動或移除。
    this.贊助金TableAdapter.Fill(this.database1DataSet.贊助金);
}
```
![螢幕擷取畫面 2025-01-20 144943](https://hackmd.io/_uploads/SJDGM_ivye.png)

## 設定 TableAdapter
如果與SQL連結後，便不可以使用DataGridView加入資料的語法了!!!!

TableAdapter 會自動生成資料操作方法，包括插入（Insert）、更新（Update）和刪除（Delete）
### 顯示、更新資料
```csharp=
this.贊助金TableAdapter.Fill(this.database1DataSet.贊助金);
```
### 新增資料
```csharp=
tableAdapter.Insert(資料1, 資料2, 資料3, 資料4);
this.贊助金TableAdapter.Fill(this.database1DataSet.贊助金);
```
### 刪除資料
```csharp=
 // 假設要刪除 ID 為 1 的資料
int idToDelete = 1;

tableAdapter.Delete(idToDelete);
this.贊助金TableAdapter.Fill(this.database1DataSet.贊助金);
```



