WinForms中如何从另一个窗体重新加载/初始化用户控件?
问题场景
- 主窗体
WindowMain点击「Roster」按钮后,在MainScreenPanel面板加载UserControlRoster用户控件 UserControlRoster包含DataGridView(显示人员花名册)和标签(如Name、Age),选中DataGridView行时标签填充对应数据- 点击Name标签弹出
DialogEditWrestlerName窗体修改姓名,修改成功后需要刷新UserControlRoster使变更生效 - 当前错误做法:保存时新建
WindowMain实例,导致重复打开主窗体,而非刷新现有控件
现有代码片段:
主窗体加载用户控件代码
MainScreenPanel.Controls.Clear(); var uc = new UserControlRoster() { Dock = DockStyle.Fill }; MainScreenPanel.Controls.Add(uc);
UserControlRoster打开编辑窗体代码
wrestlerName = lblName.Text.ToString(); DialogEditWrestlerName EditWrestlerName = new DialogEditWrestlerName(wrestlerName); EditWrestlerName.Show();
当前错误的保存代码(DialogEditWrestlerName中)
WindowMain Main = new WindowMain(); Main.Show(this); this.Close();
解决方案
方法1:通过事件通知刷新(推荐,解耦各窗体)
在DialogEditWrestlerName中定义事件,保存成功时触发,让UserControlRoster订阅事件并执行刷新。
步骤1:在DialogEditWrestlerName中添加事件
public partial class DialogEditWrestlerName : Form { // 定义保存成功事件 public event Action OnNameSaved; public DialogEditWrestlerName(string wrestlerName) { InitializeComponent(); // 初始化显示原姓名的逻辑 } private void btnSave_Click(object sender, EventArgs e) { // 执行修改姓名的业务逻辑(已确认正常) // 触发事件通知外部刷新 OnNameSaved?.Invoke(); this.Close(); } }
步骤2:在UserControlRoster中订阅事件并刷新数据
修改打开编辑窗体的代码,同时新增刷新数据的方法:
public partial class UserControlRoster : UserControl { public UserControlRoster() { InitializeComponent(); LoadRosterData(); } // 新增刷新数据方法 public void LoadRosterData() { // 重新从数据源加载DataGridView数据 // 示例:dataGridViewRoster.DataSource = GetLatestWrestlerList(); // 若用BindingSource,可调用:((BindingSource)dataGridViewRoster.DataSource).ResetBindings(false); } private void lblName_Click(object sender, EventArgs e) { string wrestlerName = lblName.Text.ToString(); DialogEditWrestlerName editForm = new DialogEditWrestlerName(wrestlerName); // 订阅保存成功事件 editForm.OnNameSaved += () => { LoadRosterData(); // 可选:重新选中当前修改的行 }; editForm.ShowDialog(); // 模态对话框更适合编辑场景 } }
方法2:通过主窗体实例刷新
在DialogEditWrestlerName中找到已打开的WindowMain实例,调用主窗体的刷新方法重新加载控件。
步骤1:在WindowMain中添加刷新方法
public partial class WindowMain : Form { public void RefreshRosterControl() { // 复用原加载控件的逻辑 MainScreenPanel.Controls.Clear(); var uc = new UserControlRoster() { Dock = DockStyle.Fill }; MainScreenPanel.Controls.Add(uc); } // 原Roster按钮点击事件(保持不变) private void btnRoster_Click(object sender, EventArgs e) { RefreshRosterControl(); } }
步骤2:在DialogEditWrestlerName的保存按钮中调用主窗体方法
private void btnSave_Click(object sender, EventArgs e) { // 执行修改姓名的业务逻辑 // 查找当前打开的主窗体实例 WindowMain mainForm = Application.OpenForms.OfType<WindowMain>().FirstOrDefault(); if (mainForm != null) { mainForm.RefreshRosterControl(); } this.Close(); }
方法3:直接刷新绑定数据源
如果UserControlRoster的DataGridView使用BindingSource绑定数据,可直接刷新数据源,无需重建控件:
public partial class UserControlRoster : UserControl { private BindingSource _rosterBindingSource; public UserControlRoster() { InitializeComponent(); _rosterBindingSource = new BindingSource(); dataGridViewRoster.DataSource = _rosterBindingSource; LoadRosterData(); } public void LoadRosterData() { var latestRoster = GetWrestlerListFromDataSource(); // 替换为你的数据源获取逻辑 _rosterBindingSource.DataSource = latestRoster; // 若仅修改单条数据,可修改后调用:_rosterBindingSource.ResetBindings(false); } }
后续通过事件或控件实例调用LoadRosterData即可完成刷新。
内容的提问来源于stack exchange,提问作者Braden Putt
相关产品推荐
相关产品推荐

