如何解决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
相关产品推荐
相关产品推荐

