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