You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决DataGridView保存数据后无法自动加载记录的问题

问题描述

用户拥有两个Windows Forms窗体:一个用于展示DataGridView数据,另一个用于添加员工信息。期望在保存员工信息后自动刷新DataGridView加载最新记录,但添加加载逻辑后仍未生效,相关C#代码如下:

public partial class PERSONAL_DETAILS_FRM : Form
{
    SqlConnection con;
    SqlCommand cmd;
    SqlDataReader dr;
    ConnectionDB db = new ConnectionDB();
    public PERSONAL_DETAILS_FRM()
    {
        InitializeComponent();
        con = new SqlConnection(db.Getconnection());
    }

    private DataGridView personal_dgv = new DataGridView();
    public void LoadDataGrid()
    {
        try
        {
            con.Open();
            using (cmd = new SqlCommand("SELECT * FROM Personal_info", con))
            {
                using (dr = cmd.ExecuteReader())
                {
                    personal_dgv.Rows.Clear();

                    while (dr.Read())
                    {
                        personal_dgv.Rows.Add(
                            dr["EmployeeID"].ToString(),
                            dr["LastName"].ToString(),
                            dr["FirstName"].ToString(),
                            dr["MiddleName"].ToString(),
                            dr["Gender"].ToString(),
                            dr["ContactNum"].ToString(),
                            dr["Email"].ToString(),
                            dr["Birthday"].ToString(),
                            dr["BirthPlace"].ToString(),
                            dr["CivilStatus"].ToString(),
                            dr["Address"].ToString());
                    }
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error loading records: " + ex.Message);
        }
        finally
        {
            if (dr != null && !dr.IsClosed)
            {
                dr.Close();
            }
            if (con.State == ConnectionState.Open)
            {
                con.Close();
            }
        }
    }

    private void save_btn_Click(object sender, EventArgs e)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(employeeID_txt.Text) ||
                string.IsNullOrWhiteSpace(LastName_txt.Text) ||
                string.IsNullOrWhiteSpace(FirstName_txt.Text) ||
                string.IsNullOrWhiteSpace(MiddleName_txt.Text) ||
                string.IsNullOrWhiteSpace(Gender_txt.Text) ||
                string.IsNullOrWhiteSpace(MobileNum_txt.Text) ||
                string.IsNullOrWhiteSpace(Email_txt.Text) ||
                string.IsNullOrWhiteSpace(Bday_txt.Text) ||
                string.IsNullOrWhiteSpace(Bplace_txt.Text) ||
                string.IsNullOrWhiteSpace(Status_txt.Text) ||
                string.IsNullOrWhiteSpace(Address_txt.Text))
            {
                MessageBox.Show("Please fill out all fields.");
                return; // Exit the method if any field is empty
            }

            con.Open();

            // Check if the ID already exists
            string checkIDQuery = "SELECT COUNT(*) FROM Personal_info WHERE EmployeeID = @EmployeeID";
            SqlCommand checkIDCmd = new SqlCommand(checkIDQuery, con);
            checkIDCmd.Parameters.AddWithValue("@EmployeeID", employeeID_txt.Text);

            int count = (int)checkIDCmd.ExecuteScalar();

            if (count > 0)
            {
                MessageBox.Show("ID already exists. Please use a different ID.");
                return; // Exit the method if ID already exists
            }

            cmd = new SqlCommand("INSERT INTO Personal_info (EmployeeID, LastName, FirstName, MiddleName, Gender, ContactNum, Email, Birthday, BirthPlace, CivilStatus, Address) VALUES (@EmployeeID, @LastName, @FirstName, @MiddleName, @Gender, @ContactNum, @Email, @Birthday, @BirthPlace, @CivilStatus, @Address)", con);

            cmd.Parameters.AddWithValue("@EmployeeID", employeeID_txt.Text);
            cmd.Parameters.AddWithValue("@LastName", LastName_txt.Text);
            cmd.Parameters.AddWithValue("@FirstName", FirstName_txt.Text);
            cmd.Parameters.AddWithValue("@MiddleName", MiddleName_txt.Text);
            cmd.Parameters.AddWithValue("@Gender", Gender_txt.Text);
            cmd.Parameters.AddWithValue("@ContactNum", MobileNum_txt.Text);
            cmd.Parameters.AddWithValue("@Email", Email_txt.Text);
            cmd.Parameters.AddWithValue("@Birthday", Bday_txt.Text);
            cmd.Parameters.AddWithValue("@BirthPlace", Bplace_txt.Text);
            cmd.Parameters.AddWithValue("@CivilStatus", Status_txt.Text);
            cmd.Parameters.AddWithValue("@Address", Address_txt.Text);

            cmd.ExecuteNonQuery();
            MessageBox.Show("Employee Details Are Saved.");            
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }
        finally
        {
            con.Close();
            LoadDataGrid();
        }
    }
}
问题分析与解决方案

核心问题1:DataGridView实例不匹配

代码中private DataGridView personal_dgv = new DataGridView();是新建了一个后台DataGridView对象,而非引用窗体设计器中已经添加到界面上的DataGridView控件。调用LoadDataGrid()时刷新的是这个后台实例,而非用户可见的界面控件,导致新记录无法显示。

修复方法:

删除手动新建的DataGridView变量,直接使用设计器生成的控件。假设窗体设计器中添加的DataGridView控件名为personal_dgv,修改LoadDataGrid()方法:

// 删除这一行:private DataGridView personal_dgv = new DataGridView();

public void LoadDataGrid()
{
    try
    {
        con.Open();
        using (cmd = new SqlCommand("SELECT * FROM Personal_info", con))
        {
            using (dr = cmd.ExecuteReader())
            {
                // 直接引用界面上的DataGridView控件
                personal_dgv.Rows.Clear();

                while (dr.Read())
                {
                    personal_dgv.Rows.Add(
                        dr["EmployeeID"].ToString(),
                        dr["LastName"].ToString(),
                        dr["FirstName"].ToString(),
                        dr["MiddleName"].ToString(),
                        dr["Gender"].ToString(),
                        dr["ContactNum"].ToString(),
                        dr["Email"].ToString(),
                        dr["Birthday"].ToString(),
                        dr["BirthPlace"].ToString(),
                        dr["CivilStatus"].ToString(),
                        dr["Address"].ToString());
                }
            }
        }
    }
    // 其余代码保持不变
}

核心问题2:跨窗体刷新逻辑缺失

如果PERSONAL_DETAILS_FRM是添加员工的窗体,而DataGridView在另一个展示窗体(比如EmployeeListForm)中,那么在添加窗体的save_btn_Click中调用LoadDataGrid()只会刷新当前窗体的控件,无法影响展示窗体。

修复方法:

以下两种方式任选其一实现跨窗体刷新:

方式1:构造函数传递展示窗体实例

在添加窗体中接收展示窗体的引用,保存后直接调用其刷新方法:

// 添加窗体的类
public partial class PERSONAL_DETAILS_FRM : Form
{
    private readonly EmployeeListForm _listForm; // 存储展示窗体实例

    // 修改构造函数,接收展示窗体
    public PERSONAL_DETAILS_FRM(EmployeeListForm listForm)
    {
        InitializeComponent();
        con = new SqlConnection(db.Getconnection());
        _listForm = listForm;
    }

    private void save_btn_Click(object sender, EventArgs e)
    {
        try
        {
            // 原有保存逻辑保持不变...
            cmd.ExecuteNonQuery();
            MessageBox.Show("Employee Details Are Saved.");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }
        finally
        {
            con.Close();
            // 调用展示窗体的刷新方法
            _listForm.LoadDataGrid();
            this.Close(); // 可选:关闭添加窗体
        }
    }
}

打开添加窗体时传入展示窗体实例:

// 在展示窗体的添加按钮点击事件中
private void addEmployeeBtn_Click(object sender, EventArgs e)
{
    var addForm = new PERSONAL_DETAILS_FRM(this);
    addForm.ShowDialog();
}
方式2:使用事件通知

在添加窗体中定义刷新事件,展示窗体订阅该事件,保存完成后触发事件刷新:

// 添加窗体的类
public partial class PERSONAL_DETAILS_FRM : Form
{
    // 定义刷新事件
    public event Action OnEmployeeSaved;

    private void save_btn_Click(object sender, EventArgs e)
    {
        try
        {
            // 原有保存逻辑保持不变...
            cmd.ExecuteNonQuery();
            MessageBox.Show("Employee Details Are Saved.");
            // 触发刷新事件
            OnEmployeeSaved?.Invoke();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }
        finally
        {
            con.Close();
            this.Close();
        }
    }
}

在展示窗体中订阅事件:

private void addEmployeeBtn_Click(object sender, EventArgs e)
{
    var addForm = new PERSONAL_DETAILS_FRM();
    addForm.OnEmployeeSaved += LoadDataGrid; // 订阅事件,触发时执行刷新
    addForm.ShowDialog();
}

额外优化建议

  • 使用SqlDataAdapter和DataTable绑定DataGridView,比手动添加行更高效且不易出错:
public void LoadDataGrid()
{
    try
    {
        using (var con = new SqlConnection(db.Getconnection()))
        {
            con.Open();
            string query = "SELECT * FROM Personal_info";
            var adapter = new SqlDataAdapter(query, con);
            var dt = new DataTable();
            adapter.Fill(dt);
            personal_dgv.DataSource = dt;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error loading records: " + ex.Message);
    }
}
  • 数据库连接使用using语句自动释放资源,避免连接泄漏风险。

内容的提问来源于stack exchange,提问作者IT ipolymer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:54:56