如何在Form Collection遍历中调用各窗体的UpdateUser公共方法?
解决方案:遍历FormCollection调用自定义UpdateUser方法
问题核心在于Application.OpenForms返回的是Form基类实例集合,而UpdateUser是你自定义的方法,基类并无此方法,因此需要通过类型转换、接口实现或反射来调用。
方案1:基于自定义基类的类型转换
如果所有需要调用UpdateUser的窗体都能继承同一个自定义基窗体,这是最类型安全的方式:
- 定义包含
UpdateUser方法的基窗体
public class BaseForm : Form { // 定义公共更新方法,可留空实现或写通用逻辑 public virtual void UpdateUser(/* 填写你的参数类型,比如UserInfo currentUser */) { } }
- 让目标窗体继承该基类并重写方法
public class OrderForm : BaseForm { public override void UpdateUser(/* 参数 */) { // 具体更新用户信息的逻辑 this.lblCurrentUser.Text = currentUser.Name; } }
- 修改遍历代码做类型转换
FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm.Visible == false && frm.Name != "FStart" && frm.Name != "FMain") { // 转换为自定义基类后调用方法 if (frm is BaseForm baseForm) { baseForm.UpdateUser(/* 传入你的用户参数 */); } frm.Show(); } }
方案2:基于接口的实现
如果不想修改窗体的继承链,可通过接口实现:
- 定义包含更新方法的接口
public interface IUserUpdatable { void UpdateUser(/* 填写参数类型 */); }
- 让目标窗体实现该接口
public class CustomerForm : Form, IUserUpdatable { public void UpdateUser(/* 参数 */) { // 具体更新逻辑 } }
- 修改遍历代码判断接口实现
FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm.Visible == false && frm.Name != "FStart" && frm.Name != "FMain") { // 判断是否实现接口,再调用方法 if (frm is IUserUpdatable updatableForm) { updatableForm.UpdateUser(/* 传入参数 */); } frm.Show(); } }
方案3:使用反射(无侵入式)
如果无法修改现有窗体代码,只能用反射调用方法:
FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm.Visible == false && frm.Name != "FStart" && frm.Name != "FMain") { // 反射获取UpdateUser方法 var updateMethod = frm.GetType().GetMethod( "UpdateUser", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance ); // 方法存在则执行调用 if (updateMethod != null) { updateMethod.Invoke(frm, new object[] { /* 传入参数,无参数则传空数组 */ }); } frm.Show(); } }
方案对比
- 方案1/2:类型安全,编译阶段即可发现错误,代码可读性高,推荐优先使用。
- 方案3:无需修改原有窗体代码,但无编译时检查,性能略低,适合无法修改窗体代码的场景。
内容的提问来源于stack exchange,提问作者M_Lyons10
相关产品推荐
相关产品推荐

