精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C# DataGridView實(shí)戰(zhàn)攻略:從小白到高手的數(shù)據(jù)表格開發(fā)秘籍

開發(fā) 前端
本文將通過3個(gè)遞進(jìn)式的實(shí)戰(zhàn)案例,幫你解決數(shù)據(jù)綁定混亂、編輯功能不生效、數(shù)據(jù)庫集成踩坑等常見問題,讓你的WinForm應(yīng)用秒變專業(yè)級(jí)!

還在為WinForm數(shù)據(jù)展示發(fā)愁?還在被DataGridView的各種屬性搞得頭暈眼花?作為一個(gè)在數(shù)據(jù)表格開發(fā)路上摸爬滾打多年的老程序員,我深知DataGridView這個(gè)"看似簡單,實(shí)則復(fù)雜"的控件給無數(shù)C#開發(fā)者帶來的困擾。今天就來和大家分享一套完整的DataGridView實(shí)戰(zhàn)攻略,從基礎(chǔ)綁定到高級(jí)應(yīng)用,讓你徹底掌握這個(gè)強(qiáng)大的數(shù)據(jù)展示利器。

本文將通過3個(gè)遞進(jìn)式的實(shí)戰(zhàn)案例,幫你解決數(shù)據(jù)綁定混亂編輯功能不生效數(shù)據(jù)庫集成踩坑等常見問題,讓你的WinForm應(yīng)用秒變專業(yè)級(jí)!

DataGridView核心武器庫

在開始實(shí)戰(zhàn)之前,我們先來認(rèn)識(shí)一下DataGridView的幾個(gè)關(guān)鍵"武器":

必知核心屬性

// 數(shù)據(jù)源綁定 - 你的數(shù)據(jù)展示基礎(chǔ)
DataSource: 支持DataTable、DataSet、List<T>等多種數(shù)據(jù)源

// 自動(dòng)列生成控制 - 避免列顯示混亂的關(guān)鍵
AutoGenerateColumns: false// 強(qiáng)烈建議手動(dòng)控制列

// 用戶操作權(quán)限控制
ReadOnly: true/false// 是否允許編輯
AllowUserToAddRows: false// 是否允許用戶添加行
AllowUserToDeleteRows: false// 是否允許用戶刪除行

// 選擇模式設(shè)置
SelectionMode: FullRowSelect // 整行選擇,用戶體驗(yàn)更好

常用操作方法

// 列操作三件套
dataGridView.Columns.Add()    // 添加列
dataGridView.Columns.Remove() // 移除列  
dataGridView.Columns.Clear()  // 清空所有列

// 數(shù)據(jù)刷新
dataGridView.Refresh()        // 手動(dòng)刷新顯示

實(shí)戰(zhàn)案例一:基礎(chǔ)數(shù)據(jù)綁定 - 告別顯示混亂

很多初學(xué)者在數(shù)據(jù)綁定時(shí)經(jīng)常遇到"列顯示不正確"、"數(shù)據(jù)對不上號(hào)"等問題。這里有一個(gè)完整的解決方案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppDataGridViewBasic
{
    publicclass Person
    {
        publicstring Name { get; set; }
        publicint Age { get; set; }
        publicstring City { get; set; }
    }
}
namespace AppDataGridViewBasic
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // 創(chuàng)建DataGridView實(shí)例
            DataGridView dataGridView = new DataGridView();
            this.Controls.Add(dataGridView);

            // ?? 關(guān)鍵配置:阻止自動(dòng)生成列
            dataGridView.AutoGenerateColumns = false;
            dataGridView.AllowUserToAddRows = false;
            dataGridView.Dock = DockStyle.Fill;
            dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            // 步驟3:手動(dòng)創(chuàng)建列(避免顯示混亂)
            CreateColumns(dataGridView);

            // 步驟4:綁定數(shù)據(jù)源
            BindData(dataGridView);
        }

        private void CreateColumns(DataGridView dgv)
        {
            // 姓名列
            var nameColumn = new DataGridViewTextBoxColumn
            {
                DataPropertyName = "Name", // ?? 必須與模型屬性名一致
                HeaderText = "姓名",
                AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
            };
            dgv.Columns.Add(nameColumn);

            // 年齡列
            var ageColumn = new DataGridViewTextBoxColumn
            {
                DataPropertyName = "Age",
                HeaderText = "年齡",
                Width = 80
            };
            dgv.Columns.Add(ageColumn);

            // 城市列
            var cityColumn = new DataGridViewTextBoxColumn
            {
                DataPropertyName = "City",
                HeaderText = "城市",
                AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
            };
            dgv.Columns.Add(cityColumn);
        }

        private void BindData(DataGridView dgv)
        {
            var people = new List<Person>
            {
                new Person { Name = "張三", Age = 28, City = "北京" },
                new Person { Name = "李四", Age = 35, City = "上海" },
                new Person { Name = "王五", Age = 42, City = "廣州" }
            };

            // ?? 金句:數(shù)據(jù)綁定一行代碼搞定
            dgv.DataSource = people;
        }
    }
}

圖片圖片

避坑指南:

  • DataPropertyName必須與模型屬性名完全一致
  • 設(shè)置AutoGenerateColumns = false避免列重復(fù)
  • 使用AutoSizeMode.Fill讓列自適應(yīng)寬度

實(shí)戰(zhàn)案例二:實(shí)時(shí)編輯功能 - 讓數(shù)據(jù)"活"起來

單純展示數(shù)據(jù)太無聊?讓我們給DataGridView加上編輯功能,實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)更新:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AppDataGridViewBasic
{
    public partial class Form2 : Form
    {
        // 數(shù)據(jù)源
        private List<Person> people;

        public Form2()
        {
            InitializeComponent();
            InitializeForm();
            LoadSampleData();
        }

        private void InitializeForm()
        {
            // ?? 開啟編輯模式的正確姿勢
            dataGridView.ReadOnly = false;

            // 注冊數(shù)據(jù)變更事件
            dataGridView.CellValueChanged += OnCellValueChanged;

            // ?? 關(guān)鍵:確保編輯完成后觸發(fā)事件
            dataGridView.CellEndEdit += OnCellEndEdit;

            // 單元格開始編輯事件
            dataGridView.CellBeginEdit += OnCellBeginEdit;

            // 數(shù)據(jù)錯(cuò)誤處理
            dataGridView.DataError += OnDataError;

            // 行刪除事件
            dataGridView.UserDeletingRow += OnUserDeletingRow;
        }

        private void LoadSampleData()
        {
            // ?? 初始化示例數(shù)據(jù)
            people = new List<Person>
            {
                new Person { Name = "張三", Age = 25, City = "北京", Email = "zhangsan@email.com", CreateDate = DateTime.Now.AddDays(-10) },
                new Person { Name = "李四", Age = 30, City = "上海", Email = "lisi@email.com", CreateDate = DateTime.Now.AddDays(-5) },
                new Person { Name = "王五", Age = 28, City = "廣州", Email = "wangwu@email.com", CreateDate = DateTime.Now.AddDays(-3) },
                new Person { Name = "趙六", Age = 35, City = "深圳", Email = "zhaoliu@email.com", CreateDate = DateTime.Now.AddDays(-1) }
            };

            // 綁定數(shù)據(jù)源
            dataGridView.DataSource = people;

            // ?? 列設(shè)置優(yōu)化
            SetupColumns();
        }

        private void SetupColumns()
        {
            if (dataGridView.Columns.Count > 0)
            {
                // 設(shè)置列標(biāo)題
                dataGridView.Columns["Name"].HeaderText = "姓名";
                dataGridView.Columns["Age"].HeaderText = "年齡";
                dataGridView.Columns["City"].HeaderText = "城市";
                dataGridView.Columns["Email"].HeaderText = "郵箱";
                dataGridView.Columns["CreateDate"].HeaderText = "創(chuàng)建時(shí)間";

                // 設(shè)置列寬比例
                dataGridView.Columns["Name"].FillWeight = 20;
                dataGridView.Columns["Age"].FillWeight = 15;
                dataGridView.Columns["City"].FillWeight = 20;
                dataGridView.Columns["Email"].FillWeight = 25;
                dataGridView.Columns["CreateDate"].FillWeight = 20;

                // 設(shè)置創(chuàng)建時(shí)間為只讀
                dataGridView.Columns["CreateDate"].ReadOnly = true;

                // 年齡列只允許數(shù)字
                dataGridView.Columns["Age"].ValueType = typeof(int);
            }
        }

        // ?? 核心事件處理方法
        private void OnCellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0) return; // 避免標(biāo)題行觸發(fā)事件

            var dgv = sender as DataGridView;
            if (dgv.DataSource is List<Person> people && e.RowIndex < people.Count)
            {
                // 獲取被修改的對象
                Person updatedPerson = people[e.RowIndex];

                // ?? 實(shí)戰(zhàn)應(yīng)用:這里可以調(diào)用業(yè)務(wù)邏輯
                SavePersonToDatabase(updatedPerson);

                // 更新狀態(tài)欄或給用戶反饋
                this.Text = $"可編輯數(shù)據(jù)表格 - 已更新:{updatedPerson.Name} 的信息 [{DateTime.Now:HH:mm:ss}]";
            }
        }

        private void OnCellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            // 確保數(shù)據(jù)驗(yàn)證和格式化
            var dgv = sender as DataGridView;
            var cell = dgv[e.ColumnIndex, e.RowIndex];

            string columnName = dgv.Columns[e.ColumnIndex].Name;

            switch (columnName)
            {
                case"Age":
                    // 年齡列數(shù)據(jù)驗(yàn)證
                    if (!int.TryParse(cell.Value?.ToString(), out int age) || age < 0 || age > 150)
                    {
                        MessageBox.Show("請輸入有效的年齡(0-150)!", "數(shù)據(jù)驗(yàn)證", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        cell.Value = 0; // 設(shè)置默認(rèn)值
                    }
                    break;

                case"Email":
                    // 郵箱格式驗(yàn)證
                    string email = cell.Value?.ToString();
                    if (!string.IsNullOrEmpty(email) && !IsValidEmail(email))
                    {
                        MessageBox.Show("請輸入有效的郵箱格式!", "數(shù)據(jù)驗(yàn)證", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        cell.Value = ""; // 清空無效郵箱
                    }
                    break;

                case"Name":
                    // 姓名不能為空
                    if (string.IsNullOrWhiteSpace(cell.Value?.ToString()))
                    {
                        MessageBox.Show("姓名不能為空!", "數(shù)據(jù)驗(yàn)證", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        cell.Value = "未命名";
                    }
                    break;
            }
        }

        private void OnCellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            // 可以在這里添加編輯前的邏輯
            var dgv = sender as DataGridView;
            string columnName = dgv.Columns[e.ColumnIndex].Name;

            // 例如:某些條件下禁止編輯
            if (columnName == "CreateDate")
            {
                e.Cancel = true; // 取消編輯
                MessageBox.Show("創(chuàng)建時(shí)間不可編輯!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void OnDataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            // 處理數(shù)據(jù)類型轉(zhuǎn)換錯(cuò)誤等
            MessageBox.Show($"數(shù)據(jù)錯(cuò)誤:{e.Exception.Message}", "錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
            e.Cancel = true;
        }

        private void OnUserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            // 刪除行前的確認(rèn)
            if (MessageBox.Show("確定要?jiǎng)h除這條記錄嗎?", "確認(rèn)刪除",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
            {
                e.Cancel = true; // 取消刪除
            }
        }

        // ?? 收藏級(jí)代碼模板:數(shù)據(jù)保存方法
        private void SavePersonToDatabase(Person person)
        {
            try
            {
                // 這里實(shí)現(xiàn)你的數(shù)據(jù)保存邏輯
                // 可以是數(shù)據(jù)庫更新、API調(diào)用等
                Console.WriteLine($"保存數(shù)據(jù):{person.Name}, {person.Age}, {person.City}, {person.Email}");

                // 模擬異步保存
                Task.Run(() => {
                    System.Threading.Thread.Sleep(100); // 模擬網(wǎng)絡(luò)延遲
                    // 實(shí)際保存到數(shù)據(jù)庫的代碼
                });

            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存失敗:{ex.Message}", "錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // ?? 按鈕事件處理
        private void BtnAdd_Click(object sender, EventArgs e)
        {
            // 添加新記錄
            people.Add(new Person
            {
                Name = "新用戶",
                Age = 20,
                City = "北京",
                Email = "new@email.com",
                CreateDate = DateTime.Now
            });

            // 刷新數(shù)據(jù)源
            RefreshDataSource();
        }

        private void BtnDelete_Click(object sender, EventArgs e)
        {
            // 刪除選中行
            if (dataGridView.SelectedRows.Count > 0)
            {
                var selectedIndex = dataGridView.SelectedRows[0].Index;
                if (selectedIndex < people.Count)
                {
                    if (MessageBox.Show("確定要?jiǎng)h除選中的記錄嗎?", "確認(rèn)刪除",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        people.RemoveAt(selectedIndex);
                        RefreshDataSource();
                    }
                }
            }
            else
            {
                MessageBox.Show("請先選擇要?jiǎng)h除的行!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void BtnSaveAll_Click(object sender, EventArgs e)
        {
            // 保存所有數(shù)據(jù)
            try
            {
                foreach (var person in people)
                {
                    SavePersonToDatabase(person);
                }
                MessageBox.Show($"成功保存 {people.Count} 條記錄!", "保存成功",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"批量保存失敗:{ex.Message}", "錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // ?? 輔助方法
        private void RefreshDataSource()
        {
            dataGridView.DataSource = null;
            dataGridView.DataSource = people;
            SetupColumns();
        }

        private bool IsValidEmail(string email)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(email);
                return addr.Address == email;
            }
            catch
            {
                returnfalse;
            }
        }

        private void Button_MouseEnter(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                btn.FlatAppearance.BorderSize = 1;
                btn.FlatAppearance.BorderColor = System.Drawing.Color.White;
            }
        }

        private void Button_MouseLeave(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                btn.FlatAppearance.BorderSize = 0;
            }
        }

        // ?? 窗體關(guān)閉時(shí)的清理工作
        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            // 取消事件訂閱,避免內(nèi)存泄漏
            if (dataGridView != null)
            {
                dataGridView.CellValueChanged -= OnCellValueChanged;
                dataGridView.CellEndEdit -= OnCellEndEdit;
                dataGridView.CellBeginEdit -= OnCellBeginEdit;
                dataGridView.DataError -= OnDataError;
                dataGridView.UserDeletingRow -= OnUserDeletingRow;
            }

            base.OnFormClosed(e);
        }


    }
}

圖片圖片

編輯模式最佳實(shí)踐:

  • 同時(shí)監(jiān)聽CellValueChanged和CellEndEdit事件
  • 做好數(shù)據(jù)驗(yàn)證,避免無效數(shù)據(jù)
  • 提供用戶反饋,提升體驗(yàn)

實(shí)戰(zhàn)案例三:數(shù)據(jù)庫集成 - 企業(yè)級(jí)應(yīng)用必備

真實(shí)項(xiàng)目中,數(shù)據(jù)往往來自數(shù)據(jù)庫。下面展示如何實(shí)現(xiàn)DataGridView與數(shù)據(jù)庫的完美集成:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Windows.Forms;

namespace AppDataGridViewBasic
{
    public partial class Form3 : Form
    {
        private DatabaseDataGridManager databaseManager;
        private readonly string connectionString = "Server=.;Database=dbtest;Integrated Security=true;";

        public Form3()
        {
            InitializeComponent();

        }

        private void InitializeForm()
        {
            try
            {
                // 初始化數(shù)據(jù)庫管理器
                databaseManager = new DatabaseDataGridManager(connectionString, dataGridView);

                // 加載數(shù)據(jù)
                databaseManager.LoadDataFromDatabase();

                // 更新狀態(tài)
                toolStripStatusLabel.Text = "? 數(shù)據(jù)庫連接成功,數(shù)據(jù)已加載";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"初始化失敗:{ex.Message}", "錯(cuò)誤",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                toolStripStatusLabel.Text = "? 數(shù)據(jù)庫連接失敗";
            }
        }

        // ?? 按鈕事件處理
        private void BtnRefresh_Click(object sender, EventArgs e)
        {
            try
            {
                databaseManager?.LoadDataFromDatabase();
                toolStripStatusLabel.Text = $"?? 數(shù)據(jù)已刷新 - {DateTime.Now:HH:mm:ss}";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"刷新失敗:{ex.Message}", "錯(cuò)誤",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BtnAddNew_Click(object sender, EventArgs e)
        {
            try
            {
                databaseManager?.AddNewRecord();
                toolStripStatusLabel.Text = $"? 新記錄已添加 - {DateTime.Now:HH:mm:ss}";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加失敗:{ex.Message}", "錯(cuò)誤",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BtnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView.SelectedRows.Count > 0)
                {
                    var result = MessageBox.Show("確定要?jiǎng)h除選中的記錄嗎?", "確認(rèn)刪除",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                    if (result == DialogResult.Yes)
                    {
                        databaseManager?.DeleteSelectedRecord(dataGridView.SelectedRows[0].Index);
                        toolStripStatusLabel.Text = $"??? 記錄已刪除 - {DateTime.Now:HH:mm:ss}";
                    }
                }
                else
                {
                    MessageBox.Show("請先選擇要?jiǎng)h除的行!", "提示",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"刪除失敗:{ex.Message}", "錯(cuò)誤",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BtnSaveChanges_Click(object sender, EventArgs e)
        {
            try
            {
                databaseManager?.SaveAllChanges();
                toolStripStatusLabel.Text = $"?? 所有更改已保存 - {DateTime.Now:HH:mm:ss}";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存失敗:{ex.Message}", "錯(cuò)誤",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 按鈕懸停效果
        private void Button_MouseEnter(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                btn.FlatAppearance.BorderSize = 1;
                btn.FlatAppearance.BorderColor = Color.White;
            }
        }

        private void Button_MouseLeave(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                btn.FlatAppearance.BorderSize = 0;
            }
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            databaseManager?.Dispose();
            base.OnFormClosed(e);
        }

        private void Form3_Load(object sender, EventArgs e)
        {
            InitializeForm();
        }
    }

    // ?? 企業(yè)級(jí)數(shù)據(jù)庫管理器
    publicclass DatabaseDataGridManager : IDisposable
    {
        private readonly string connectionString;
        private DataGridView dataGridView;
        private DataTable dataTable;
        private SqlDataAdapter dataAdapter;
        private SqlCommandBuilder commandBuilder;

        public DatabaseDataGridManager(string connStr, DataGridView dgv)
        {
            connectionString = connStr;
            dataGridView = dgv;
            InitializeDataGrid();
        }

        private void InitializeDataGrid()
        {
            // ?? 企業(yè)級(jí)配置
            dataGridView.AutoGenerateColumns = true; // 數(shù)據(jù)庫場景可以自動(dòng)生成
            dataGridView.ReadOnly = false;
            dataGridView.AllowUserToDeleteRows = false; // 安全起見
            dataGridView.AllowUserToAddRows = false; // 通過按鈕控制

            // 注冊事件
            dataGridView.CellValueChanged += OnDatabaseCellChanged;
            dataGridView.CellEndEdit += OnCellEndEdit;
        }

        // ?? 收藏級(jí)方法:加載數(shù)據(jù)庫數(shù)據(jù)
        public void LoadDataFromDatabase()
        {
            try
            {
                using (var connection = new SqlConnection(connectionString))
                {
                    // 創(chuàng)建適配器和命令構(gòu)建器
                    dataAdapter = new SqlDataAdapter("SELECT * FROM People ORDER BY Id", connection);
                    commandBuilder = new SqlCommandBuilder(dataAdapter);

                    dataTable = new DataTable();

                    // ?? 關(guān)鍵:Fill方法一次性完成連接、查詢、斷開
                    dataAdapter.Fill(dataTable);

                    dataGridView.DataSource = dataTable;

                    // 美化顯示
                    FormatColumns();
                }
            }
            catch (SqlException sqlEx)
            {
                if (sqlEx.Number == 2) // 服務(wù)器未找到
                {
                    thrownew Exception("無法連接到SQL Server,請檢查服務(wù)器是否運(yùn)行");
                }
                elseif (sqlEx.Number == 208) // 表不存在
                {
                    CreateSampleTable();
                    LoadDataFromDatabase(); // 重新加載
                }
                else
                {
                    thrownew Exception($"數(shù)據(jù)庫錯(cuò)誤:{sqlEx.Message}");
                }
            }
            catch (Exception ex)
            {
                thrownew Exception($"數(shù)據(jù)加載失敗:{ex.Message}");
            }
        }

        private void CreateSampleTable()
        {
            try
            {
                using (var connection = new SqlConnection(connectionString))
                {
                    connection.Open();

                    var createTableCommand = new SqlCommand(@"
                        IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='People' AND xtype='U')
                        CREATE TABLE People (
                            Id INT IDENTITY(1,1) PRIMARY KEY,
                            Name NVARCHAR(50) NOT NULL,
                            Age INT NOT NULL,
                            City NVARCHAR(50),
                            Email NVARCHAR(100),
                            CreateDate DATETIME DEFAULT GETDATE()
                        )", connection);

                    createTableCommand.ExecuteNonQuery();

                    // 插入示例數(shù)據(jù)
                    var insertCommand = new SqlCommand(@"
                        INSERT INTO People (Name, Age, City, Email) VALUES
                        (N'張三', 25, N'北京', 'zhangsan@email.com'),
                        (N'李四', 30, N'上海', 'lisi@email.com'),
                        (N'王五', 28, N'廣州', 'wangwu@email.com'),
                        (N'趙六', 35, N'深圳', 'zhaoliu@email.com')", connection);

                    insertCommand.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                thrownew Exception($"創(chuàng)建示例表失敗:{ex.Message}");
            }
        }

        private void FormatColumns()
        {
            // 等待列生成完成
            if (dataGridView.Columns.Count == 0)
            {
                dataGridView.Refresh();
                Application.DoEvents(); // 確保UI更新完成
            }

            try
            {
                // ?? 安全檢查每一列
                var idColumn = dataGridView.Columns["Id"];
                if (idColumn != null)
                {
                    idColumn.HeaderText = "編號(hào)";
                    idColumn.ReadOnly = true;
                    idColumn.DefaultCellStyle.BackColor = Color.LightGray;
                    idColumn.Width = 60;
                }

                var nameColumn = dataGridView.Columns["Name"];
                if (nameColumn != null)
                {
                    nameColumn.HeaderText = "姓名";
                    nameColumn.Width = 100;
                }

                var ageColumn = dataGridView.Columns["Age"];
                if (ageColumn != null)
                {
                    ageColumn.HeaderText = "年齡";
                    ageColumn.Width = 60;
                }

                var cityColumn = dataGridView.Columns["City"];
                if (cityColumn != null)
                {
                    cityColumn.HeaderText = "城市";
                    cityColumn.Width = 100;
                }

                var emailColumn = dataGridView.Columns["Email"];
                if (emailColumn != null)
                {
                    emailColumn.HeaderText = "郵箱";
                    emailColumn.Width = 150;
                }

                var createDateColumn = dataGridView.Columns["CreateDate"];
                if (createDateColumn != null)
                {
                    createDateColumn.HeaderText = "創(chuàng)建時(shí)間";
                    createDateColumn.ReadOnly = true;
                    createDateColumn.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
                }
            }
            catch (Exception ex)
            {
                // 記錄日志但不中斷程序
                System.Diagnostics.Debug.WriteLine($"列格式化警告: {ex.Message}");
            }
        }

        private void OnDatabaseCellChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0) return;

            try
            {
                // 標(biāo)記行為已修改
                DataRow modifiedRow = dataTable.Rows[e.RowIndex];
                // DataRow會(huì)自動(dòng)跟蹤更改狀態(tài)
            }
            catch (Exception ex)
            {
                MessageBox.Show($"數(shù)據(jù)更改失敗:{ex.Message}", "錯(cuò)誤");
                // 回滾更改
                dataTable.RejectChanges();
                dataGridView.Refresh();
            }
        }

        private void OnCellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            var dgv = sender as DataGridView;
            var cell = dgv[e.ColumnIndex, e.RowIndex];
            string columnName = dgv.Columns[e.ColumnIndex].Name;

            // 數(shù)據(jù)驗(yàn)證
            switch (columnName)
            {
                case"Age":
                    if (!int.TryParse(cell.Value?.ToString(), out int age) || age < 0 || age > 150)
                    {
                        MessageBox.Show("請輸入有效的年齡(0-150)!", "數(shù)據(jù)驗(yàn)證");
                        cell.Value = DBNull.Value;
                        return;
                    }
                    break;
                case"Name":
                    if (string.IsNullOrWhiteSpace(cell.Value?.ToString()))
                    {
                        MessageBox.Show("姓名不能為空!", "數(shù)據(jù)驗(yàn)證");
                        cell.Value = "未命名";
                        return;
                    }
                    break;
                case"Email":
                    string email = cell.Value?.ToString();
                    if (!string.IsNullOrEmpty(email) && !IsValidEmail(email))
                    {
                        MessageBox.Show("請輸入有效的郵箱格式!", "數(shù)據(jù)驗(yàn)證");
                        cell.Value = DBNull.Value;
                        return;
                    }
                    break;
            }
        }

        // ?? 企業(yè)級(jí)更新方法:批量保存所有更改
        public void SaveAllChanges()
        {
            try
            {
                if (dataAdapter != null && dataTable != null)
                {
                    // ?? 重新創(chuàng)建連接和適配器
                    using (var connection = new SqlConnection(connectionString))
                    {
                        // 重新設(shè)置適配器的連接
                        dataAdapter.SelectCommand.Connection = connection;

                        // 重新生成Insert、Update、Delete命令
                        commandBuilder = new SqlCommandBuilder(dataAdapter);

                        // 執(zhí)行更新
                        dataAdapter.Update(dataTable);
                        dataTable.AcceptChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                thrownew Exception($"保存失敗:{ex.Message}");
            }
        }

        public void AddNewRecord()
        {
            try
            {
                DataRow newRow = dataTable.NewRow();
                newRow["Name"] = "新用戶";
                newRow["Age"] = 20;
                newRow["City"] = "北京";
                newRow["Email"] = "new@email.com";

                dataTable.Rows.Add(newRow);
            }
            catch (Exception ex)
            {
                thrownew Exception($"添加記錄失敗:{ex.Message}");
            }
        }

        public void DeleteSelectedRecord(int rowIndex)
        {
            try
            {
                if (rowIndex >= 0 && rowIndex < dataTable.Rows.Count)
                {
                    dataTable.Rows[rowIndex].Delete();
                }
            }
            catch (Exception ex)
            {
                thrownew Exception($"刪除記錄失敗:{ex.Message}");
            }
        }

        private bool IsValidEmail(string email)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(email);
                return addr.Address == email;
            }
            catch
            {
                returnfalse;
            }
        }

        public void Dispose()
        {
            dataAdapter?.Dispose();
            commandBuilder?.Dispose();
            dataTable?.Dispose();

            if (dataGridView != null)
            {
                dataGridView.CellValueChanged -= OnDatabaseCellChanged;
                dataGridView.CellEndEdit -= OnCellEndEdit;
            }
        }
    }
}

圖片圖片

數(shù)據(jù)庫集成避坑指南:

  • 使用using語句確保連接正確釋放
  • 做好異常處理,避免程序崩潰
  • 實(shí)現(xiàn)數(shù)據(jù)回滾機(jī)制,保證數(shù)據(jù)一致性

高手進(jìn)階技巧

性能優(yōu)化秘籍

// 大量數(shù)據(jù)加載時(shí)暫停重繪,提升性能
dataGridView.SuspendLayout();
// ... 進(jìn)行數(shù)據(jù)操作
dataGridView.ResumeLayout();

// 虛擬模式處理海量數(shù)據(jù)
dataGridView.VirtualMode = true;

用戶體驗(yàn)增強(qiáng)

// 隔行變色
dataGridView.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;

// 鼠標(biāo)懸停高亮
dataGridView.DefaultCellStyle.SelectionBackColor = Color.DodgerBlue;

總結(jié):掌握DataGridView的三個(gè)關(guān)鍵點(diǎn)

通過以上三個(gè)遞進(jìn)式案例,相信你已經(jīng)對DataGridView有了全面的認(rèn)識(shí)。讓我來總結(jié)三個(gè)最重要的要點(diǎn):

  1. 數(shù)據(jù)綁定的正確姿勢手動(dòng)控制列生成,避免顯示混亂
  2. 編輯功能的完整實(shí)現(xiàn)事件處理+數(shù)據(jù)驗(yàn)證+用戶反饋
  3. 數(shù)據(jù)庫集成的企業(yè)級(jí)方案異常處理+事務(wù)管理+性能優(yōu)化

DataGridView雖然功能強(qiáng)大,但掌握了正確的使用方法,它就會(huì)成為你開發(fā)WinForm應(yīng)用的得力助手。記住,實(shí)踐是最好的老師,建議大家把這些代碼在自己的項(xiàng)目中跑一遍,相信會(huì)有更深的理解!

責(zé)任編輯:武曉燕 來源: 技術(shù)老小子
相關(guān)推薦

2023-11-02 08:53:26

閉包Python

2017-07-11 09:35:10

大數(shù)據(jù)linuxjava

2023-06-09 00:09:46

MySQL分庫分表

2017-10-10 17:36:14

大數(shù)據(jù)語言人工智能

2018-06-19 14:07:04

Python編程開發(fā)面向?qū)ο?/a>

2025-11-06 00:05:00

2009-05-21 09:28:20

C#DatagridVie操作

2025-03-25 09:00:00

2017-08-10 13:43:00

大數(shù)據(jù)數(shù)據(jù)表格優(yōu)化設(shè)計(jì)

2020-11-05 08:14:17

鏈表

2025-02-14 00:00:20

C#C/C++語言

2023-11-08 09:10:23

pytestPython

2024-06-20 09:58:19

C#Attribute元數(shù)據(jù)機(jī)制

2009-08-19 10:46:48

C#操作Word表格

2009-08-19 10:42:08

C#操作Word表格

2019-08-16 09:55:22

Pandas編程語言代碼

2009-04-09 09:19:25

C#規(guī)則表達(dá)式.NET

2025-04-27 08:20:00

前端配置文件開發(fā)

2009-08-12 18:16:47

C#類型比較

2021-08-26 06:58:15

Docker容器數(shù)據(jù)卷
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲高清视频一区| 88国产精品欧美一区二区三区| 美女黄色片视频| 老司机av在线免费看| 成人综合婷婷国产精品久久蜜臀 | 日韩欧美中文在线| 亚洲精品欧美精品| 高h震动喷水双性1v1| 日韩av二区在线播放| 欧美精品中文字幕一区| 亚洲成人日韩在线| 欧美日韩va| 欧美日韩国产专区| 亚洲精品自在在线观看| 日本免费不卡视频| 国内精品国产成人| 国产成人亚洲综合91精品| 青草影院在线观看| 日韩精品一区二区三区免费观影 | 一本色道久久综合一区| 久久手机免费视频| 国精产品一区二区三区| 成人春色在线观看免费网站| 5566中文字幕一区二区电影| 日韩中文字幕av| 亚洲天堂2018av| 成人影院在线视频| 亚洲免费在线观看视频| 青青草国产精品| 成人免费一级视频| 国产一区不卡视频| 国产区精品视频| av大全在线观看| 精品动漫3d一区二区三区免费版 | 日韩一区不卡| 先锋av资源站| 成人激情免费电影网址| 亚洲aⅴ日韩av电影在线观看 | 99riav视频在线观看| 自拍偷拍亚洲欧美日韩| 亚洲欧美久久234| 国产人成在线视频| 久久久亚洲高清| 精品国产乱码久久久久软件| 人成网站在线观看| 国产69精品久久久久毛片| 亚洲999一在线观看www| 国产免费不卡视频| 激情欧美日韩一区二区| 国产欧洲精品视频| 91精品在线视频观看| 日本成人在线电影网| 国产不卡一区二区在线播放| 欧美日韩综合一区二区三区| 香蕉亚洲视频| 日本欧美在线视频| 波多野结衣家庭主妇| 首页欧美精品中文字幕| 日韩av电影在线网| 无码人妻精品一区二区蜜桃色欲| 日韩高清电影一区| 国产日韩欧美黄色| av高清一区二区| 国产ts人妖一区二区| 国产欧美日韩一区二区三区| 少妇人妻偷人精品一区二区 | 日韩欧美在线网站| 91精产国品一二三| 乱亲女h秽乱长久久久| 精品亚洲一区二区三区在线播放 | 男人的天堂免费| 精品福利一区| 亚洲色图第三页| 国产视频123区| 中文字幕一区二区三区乱码图片| 欧美国产日韩一区| 久久精品视频1| 奇米影视7777精品一区二区| 91精品啪aⅴ在线观看国产| 亚洲av综合色区无码一二三区| 成人少妇影院yyyy| 日本一区二区三区免费看| 91露出在线| 一级中文字幕一区二区| 日韩国产欧美亚洲| 国产精品xxx| 日韩精品一区二区三区在线| 精品人妻少妇嫩草av无码| 成人羞羞动漫| 久久久免费高清电视剧观看| 无码人妻黑人中文字幕| 国产精品影视在线| 欧美精品一区在线| www国产在线观看| 黑人巨大精品欧美一区二区三区 | 91麻豆精品国产综合久久久| 亚洲精品一区二区三区四区高清| av女人的天堂| 国产字幕视频一区二区| 日韩av免费在线看| 超碰人人人人人人| 日本一区二区综合亚洲| 91成人综合网| 看片一区二区| 亚洲精品自拍视频| 97成人资源站| 日韩电影免费一区| 国内视频一区| 麻豆影视在线观看_| 欧美午夜片在线免费观看| 欧美性受xxxx黒人xyx性爽| 九九综合九九| 国模精品系列视频| 国产深喉视频一区二区| 国产欧美久久久精品影院| 欧美久久久久久久久久久久久久| av亚洲一区| 亚洲精品自拍第一页| 国产一级大片在线观看| 国产一区二区三区四| 日韩欧美视频第二区| 国内激情视频在线观看| 日韩无一区二区| 萌白酱视频在线| 久久香蕉精品| 九九久久99| 岛国在线视频网站| 精品久久久久久久久久久久久久久久久 | 亚洲天堂av片| 成人午夜免费电影| 免费成人进口网站| 天天综合在线观看| 在线视频精品一| 麻豆精品久久久久久久99蜜桃| 成人精品一区二区三区四区| 日韩中文在线字幕| 婷婷久久免费视频| 丝袜亚洲欧美日韩综合| 91青青草视频| 国产日韩欧美一区二区三区乱码 | 男人av在线播放| 精品日韩一区二区| 青春草免费视频| 国产美女视频一区| 亚洲国产精品日韩专区av有中文| 欧美精品入口| 欧美一级视频一区二区| 色欲av伊人久久大香线蕉影院| 亚洲一区在线电影| 性猛交╳xxx乱大交| 欧美在线免费| aa日韩免费精品视频一| 污视频网站在线免费| 欧美一级艳片视频免费观看| 欧美一区二区三区爽爽爽| 国产麻豆精品一区二区| 三级在线免费观看| a级日韩大片| 97在线视频一区| 水莓100在线视频| 一本色道**综合亚洲精品蜜桃冫| 在线国产视频一区| 日韩av中文字幕一区二区| 天堂资源在线亚洲资源| 欧美日韩伦理一区二区| 九九热精品在线| 天天av天天翘| 91久久国产最好的精华液| 能直接看的av| 国产一区二区久久| 免费不卡av在线| 国产精欧美一区二区三区白种人| 亚州国产精品| 国产精品视频一| av免费网站在线| 亚洲精品av在线| 波多野结衣电车痴汉| 国产精品久久99| 免费在线观看日韩av| 激情久久久久| 日本一区二区久久精品| www.久久久.com| 性欧美xxxx交| aⅴ在线视频男人的天堂| 欧美一区二区二区| 成人毛片18女人毛片| 国产精品久久毛片| 97人妻精品一区二区三区免费 | 久久精品国产成人| 国产91久久久| 在线亚洲高清视频| 欧美成人精品激情在线视频| 久久综合狠狠综合久久激情| 日本黄色福利视频| 亚洲精品欧美| 伊人久久大香线蕉av一区| gogo人体一区| 国产欧美日韩亚洲精品| a级片在线免费观看| 最近2019好看的中文字幕免费| 性欧美一区二区三区| 在线视频一区二区三区| 欧美黄色免费看| 国产免费成人在线视频| 高清中文字幕mv的电影| 久久国产精品免费| 色综合久久久久无码专区| 91精品精品| 日韩一区二区电影在线观看| 女同另类激情重口| 91美女福利视频高清| 欧洲一级精品| 91精品国产九九九久久久亚洲| 免费黄网站在线播放| 亚洲精品在线观看www| xxxx18国产| 欧美精品久久99久久在免费线 | 精品众筹模特私拍视频| 日韩在线观看网站| 国产美女视频一区二区三区 | 欧美视频第二页| 久久久午夜影院| 中文字幕永久在线不卡| 欧美大波大乳巨大乳| 99热99精品| 欧美熟妇精品一区二区| 久久精品国产精品青草| 黄色一级免费大片| 免费永久网站黄欧美| 精品无码国模私拍视频| 欧美日韩一区二区高清| 亚洲成人动漫在线| 999视频精品| 亚洲一区二区在线观| 青青草原综合久久大伊人精品 | 妖精视频一区二区| 国产成人av电影| 国产chinesehd精品露脸| 国产成人丝袜美腿| 免费高清视频在线观看| 国产成人综合视频| 亚洲成人福利视频| 国产aⅴ精品一区二区三区色成熟| 樱花草www在线| 国产一区二区三区免费播放| 欧美性受xxxxxx黑人xyx性爽| 蜜桃久久av一区| 亚洲一区在线不卡| 日本中文字幕不卡| 国产精品区在线| 久久国产麻豆精品| 五月天激情播播| 国产一区高清在线| 久久久久亚洲av片无码v| 国产精品综合一区二区三区| 免费不卡av网站| 国产suv精品一区二区883| 图片区偷拍区小说区| 成人午夜视频在线| 日韩一级视频在线观看| 久久精品免费在线观看| 国产一二三av| 亚洲视频一区二区在线| 九九热精彩视频| 亚洲国产wwwccc36天堂| 日韩欧美成人一区二区三区| 日本丶国产丶欧美色综合| 中文字幕一区二区人妻痴汉电车| 欧美日本高清视频在线观看| 精品国产无码一区二区三区| 亚洲精品720p| 国产小视频福利在线| www日韩中文字幕在线看| a级在线观看| 97热在线精品视频在线观看| 久久天堂av| 91色视频在线导航| 牛牛精品成人免费视频| 日韩在线国产| 综合激情网站| 日本精品免费在线观看| 激情综合色综合久久综合| 99久久久无码国产精品性波多| 久久久久久久久久久久久久久99| 一本一本久久a久久| 亚洲永久精品大片| 中文字幕69页| 日韩欧美三级在线| 国产视频福利在线| 裸体女人亚洲精品一区| 亚洲欧美小说色综合小说一区| 国产精品视频99| 老牛精品亚洲成av人片| 性刺激综合网| 9久re热视频在线精品| 国产福利在线免费| www.亚洲精品| 精品国产大片大片大片| 天天色天天爱天天射综合| 亚洲综合一区中| 亚洲成人精品久久| 欧美人xxx| 欧洲亚洲免费视频| 日韩欧美高清一区二区三区| 欧美在线播放一区二区| 亚洲精品乱码| 亚洲自拍第三页| 国产三级一区二区三区| 日本a在线观看| 91精品国产综合久久小美女| 国产露出视频在线观看| 97视频在线观看网址| 日韩欧美中文字幕在线视频 | 菠萝蜜视频国产在线播放| 国产aⅴ夜夜欢一区二区三区| 成人资源在线| 色一情一乱一乱一区91| 麻豆精品在线看| 亚洲一级中文字幕| 亚洲观看高清完整版在线观看| 97久久人国产精品婷婷 | 日本h片在线观看| 成人h片在线播放免费网站| 精品久久91| 免费日韩视频在线观看| caoporn国产一区二区| 欧美精品一区二区成人| 91精品国产91久久综合桃花 | 高清欧美一区二区三区| 国产精品一站二站| 在线精品日韩| 免费观看日韩av| 国产精品美女高潮无套| 欧美性猛交xxx| 日韩美女一级视频| 69av成年福利视频| 狠狠一区二区三区| 精品成在人线av无码免费看| 成人午夜av电影| 国产亚洲精品久久久久久无几年桃| 91麻豆精品国产91久久久久久久久 | 7777久久亚洲中文字幕| 中文字幕日韩高清| 日韩漫画puputoon| 亚洲精品日韩在线观看| 毛片av中文字幕一区二区| 91中文字幕永久在线| 欧美日韩亚洲网| 亚洲日本在线播放| 欧日韩不卡在线视频| 久久最新网址| 日本久久久久久久久久久久| 国产精品网站在线观看| 中文字幕在线视频免费| 久久激情五月丁香伊人| 成人免费观看49www在线观看| 国产又粗又爽又黄的视频 | 右手影院亚洲欧美| 欧美性猛交xxxx富婆| 国产高清一区在线观看| 国产精品爽爽爽| 亚洲成av人片一区二区密柚| 香蕉视频xxx| 亚洲高清视频中文字幕| 欧美亚洲日本| 国产精品久久久久久久久久久新郎| 成人嫩草影院| 69久久精品无码一区二区| 亚洲午夜精品一区二区三区他趣| 日本人妻丰满熟妇久久久久久| 2019亚洲男人天堂| 青青草97国产精品麻豆| 真实乱偷全部视频| 精品色蜜蜜精品视频在线观看| 国产专区在线播放| 91精品视频在线| 亚洲精品国产日韩| 国产欧美一区二区三区在线观看视频| 555夜色666亚洲国产免| а√在线中文在线新版| 日韩在线三区| 国产iv一区二区三区| 久久久蜜桃一区二区| 久久综合电影一区| 人人精品视频| 91亚洲精品久久久蜜桃借种| 午夜影院在线观看欧美| 国产系列在线观看| 99在线视频首页| 秋霞电影网一区二区| 精品少妇theporn| 视频在线观看一区二区| 国产精品tv| jizzzz日本| 欧美日韩中文在线| 手机在线免费看av| 亚洲图片都市激情| 91免费视频大全| www.热久久| 成人写真视频福利网|