# C#Form DataGridView with database
就是將DataGridView與database進行連結
順便教一下相關的創建等等
## 目錄
> [TOC]
## 加入database
加入它內建的資料庫


點擊開啟Database

於伺服器總管加入新的資料表

然後就可以開始來設定資料類型與名稱

* 資料類型:
* int為數字
* nchar(5)為文字,括號後面就是可以輸入的資料長度
於下方程式碼更改程式名稱
更改姓名[Table]>>>[贊助金]
```
CREATE TABLE [dbo].[Table] //這裡更改
(
[Id] INT NOT NULL PRIMARY KEY,
[name] NCHAR(15) NULL,
[性別] NCHAR(10) NULL,
[贊助金額] NCHAR(25) NULL
)
```
按下左上角更新上傳設定結果>>更新資料庫結果

於伺服器總管底下,按再重新整理一次,更新更改資料

右鍵點擊資料庫名稱,顯示資料表資料,即可開始加入資料
資料都加入完畢後,點擊資料上方的更新鍵上傳即可

## DataGridView
這是一個存取資料所使用的,類似於以下
| 欄位 1 | 欄位 2 | 欄位 3 |
| -------- | -------- | -------- |
| 資料 1 | 資料 2 | 資料 3 |
|資料 4 |資料 5 |資料 6|
### 資料設定
DataGridView的左上角就可以進行資料編輯

### 加入資料
```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();
```
### 各種類型欄位使用
也可以直接使用點擊的設定:

✅ 範例: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左上角設定當中>>>點擊選擇資料來源>>>點擊底部的加入資料來源>>>接下來點選資料庫>>>一路按下一部即可>>>最後選擇自己的資料庫上傳

如果有加入成功在表單載入時應該會自動顯示
```csharp=
private void Form3_Load(object sender, EventArgs e)
{
//TODO:這行程式碼會將資料載入'database1DataSet.贊助金'資料表 您可以視需要進行移動或移除。
this.贊助金TableAdapter.Fill(this.database1DataSet.贊助金);
}
```

## 設定 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.贊助金);
```