简体   繁体   English

C#winforms在运行时实例化未知(在设计时)表单(后期绑定?)

[英]C# winforms instantiating unknown (at design time) form at runtime (late binding?)

I have a need to instantiate an instance of a dll containing a form at runtime. 我需要在运行时实例化包含窗体的dll实例。 Currently I have a long switch statement with 75+ cases and growing rapidly. 目前,我有一个超过75个案例的长篇陈述,并且发展迅速。 As this has all developed we have also developed a List that contains all the info to dynamically call the form. 随着这一切的发展,我们还开发了一个List,其中包含用于动态调用表单的所有信息。

Sample case now 现在提供样品盒

...
case "state"
  State state = new State();
  state.Parent = this.Parent;
  state.ScreenNameLong = "State ";
  state.ScreenTitle = "St11 - State";
  state.SetupForm();
  this.OpenForm(state, state.ScreenTitle);
  break;
...

All info needed is now contained in a list element called menuItem which is already selected. 现在,所需的所有信息都包含在名为menuItem的列表元素中,该元素已被选中。 It has form ("State"), ScreenNameLong, ScreenTitle etc.. All forms to be called have Parent objects and SetupForm() methods. 它具有表单(“状态”),ScreenNameLong,ScreenTitle等。所有要调用的表单都有Parent对象和SetupForm()方法。

All dll's are referenced in "using" statements and in project references. 在“使用”语句和项目引用中都引用了所有dll。 It seems I should somehow be able to do something similar to this, once: 似乎我应该以某种方式能够执行类似的操作:

Form formToLaunch = (menuItem.form);
formToLaunch.Parent = this.Parent;
formToLaunch.ScreenNameLong = menuItem.descr;
formToLaunch.ScreenTitle = menuItem.scrNumber + " " + formToLaunch.ScreenNameLong;
formToLaunch.SetupForm();
this.OpenForm(formToLaunch, formToLaunch.ScreenNameLong );

I have beat my head against the wall and not found a good solution to this. 我已经把头撞在墙上,却找不到一个好的解决方案。 I have researched using Reflection and Interfaces and they don't seem to fit the bill, or I am just not getting it... 我已经使用反射和接口进行了研究,但它们似乎不符合要求,或者我只是不理解而已...

All your forms will need to implement an interface defining the common members, for example: 您的所有表单都需要实现定义公共成员的接口,例如:

interface IForm : IDisposable
{
    Form Parent { get; set; }
    string ScreenNameLong { get; set; }
    string ScreenTitle { get; set; }
    void SetupForm();
}

Here IForm inherits from IDisposable per dbc's comment below. 在此, IForm继承自IDisposableIForm以下dbc的注释。

Get the Type from the typename (presumably in your menuItem.form ). 从类型名称中获取Type(大概在您的menuItem.form )。 You might need to play around with this: 您可能需要尝试一下:

var type = Type.GetType("form_namespace." + menuItem.form + ", form_assembly_name");

Instantiate the type, cast as your interface, and do whatever you want with it: 实例化类型,将其强制转换为您的接口,然后使用它进行任何操作:

var formToLaunch = Activator.CreateInstance(type) as IForm;
if (formToLaunch != null)
{
    formToLaunch.Parent = this.Parent;
    formToLaunch.ScreenNameLong = menuItem.descr;
    formToLaunch.ScreenTitle = menuItem.scrNumber + " " + formToLaunch.ScreenNameLong;
    formToLaunch.SetupForm();
    this.OpenForm(formToLaunch, formToLaunch.ScreenNameLong);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM