【发布时间】:2011-01-28 19:10:17
【问题描述】:
好的,我整天都在思考这个想法,我已经到了我承认我完全不知道的部分。可能我正在做的事情很愚蠢,有更好的方法,但这就是我的想法带给我的地方。
我正在尝试使用通用方法在 WinForms 中加载表单:
protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new()
{
// Do some stuff
}
表单由 ToolStripMenuItem 加载(通过选择项或使用打开 Windows 菜单项)。它们是延迟加载的,因此在 MDI 父级中存在表单字段,但在需要它们之前它们为空。我有一个用于处理所有菜单项单击的 ToolStripMenuItem_Click 的通用方法。除了 ToolStripMenuItem 的名称与为它们对应的表单类名称选择的模式相匹配之外,该方法无法真正知道正在调用哪个表单。因此,使用 ToolStripMenuItem 的名称,我可以推测所请求的表单类型的名称以及分配用于存储该表单引用的私有字段的名称。
使用它,我可以使用具有硬编码类型和字符串匹配的增长/收缩 switch 语句来调用具有特定类型集的方法(不受欢迎),或者我可以使用反射来获取字段并创建实例方式。我的问题是,System.Activator.CreateInstance 提供了一个无法转换为我需要的类型的 ObjectHandler。这是我目前所拥有的 sn-p:
string formName = "_form" + ((ToolStripMenuItem)sender).Name.Replace("ToolStripMenuItem", "");
string formType = formName.Substring(1);
FieldInfo fi = this.GetType().GetField(formName, BindingFlags.NonPublic | BindingFlags.Instance);
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
formToLoad = (????)System.Activator.CreateInstance("MyAssemblyName", formType);
}
this.LoadForm(ref formToLoad, false);
fi.SetValue(this, formToLoad);
我知道用于 (????) 的类型的字符串名称,但在编译时我不知道类型,因为它会更改。我已经尝试了很多方法来让这个演员/实例化工作,但没有一个成功。我非常想知道是否有可能只知道类型作为字符串来执行这样的转换。我尝试使用Type.GetType(string, string) 执行强制转换,但编译器不喜欢它。如果有人因为我只是愚蠢地这样做而对如何动态加载表单有不同的想法,请告诉我。
【问题讨论】:
-
制作 formToLoad 对象,并在 LoadForm 和 SetValue 点将其转换为 FormWithWorker?
标签: c# winforms reflection casting