我正在尝试使用户控件像插件一样工作:从用户的选择中动态加载(使用反射)。单击按钮后,我可以看到UI已经调整为应该指示用户控件已加载但我无法控制自身。我甚至使用了viewstate,但我仍然看不到控件。
请在下面找到我的代码:
protected void Page_Load(object sender, EventArgs e)
{
//the scenario should be: a user clicking a button and from there,
//loads the control just below it, but still in the same page.
if (Page.IsPostBack)
LoadUserControl();
//(a)I also tried to put in a ViewState but still nothing happens.
//if (ViewState["UserControl"] != null)
//{
// UserControl uc = (UserControl)ViewState["UserControl"];
// pnlReportControl.Controls.Add(LoadControl());
//}
}
//supposedly done after a button click
private void LoadUserControl()
{
enrolmentReports = string.Concat(Server.MapPath("~"), enrolmentDll);
assembly = Assembly.LoadFrom(enrolmentReports);
Type type = assembly.GetType("TZEnrollmentReports.EnrollmentUserControl");
enrolmentMethodInfos = type.GetMethods();
//also tried this way but also didn't work
//Page.LoadControl(type, null);
UserControl uc1 = (UserControl)LoadControl(type, null);
pnlReportControl.Controls.Add(uc1);
//(a)
//ViewState["UserControl"] = uc1;
}
请帮忙。这只是整个复杂过程的第一步。我仍然需要从该报告中获取数据集。但我想我会把它留给另一个线程。
谢谢!
答案 0 :(得分:1)
我认为这是LoadControl(Type, Object)
的设计,它不会返回你所期望的。
如果您将其更改为使用LoadControl("PathOfControl")
,那么这应该有效。
有关详情Dynamically Loading a UserControl with LoadControl Method (Type, object[])
,请参阅此SO Q& A.答案 1 :(得分:1)
可以帮助您解决此问题的建议是改变一点方法。通常开发可插拔系统,您可以将可插拔性基于某些接口。在您的情况下,我将创建一个接口IPlugin
,用于定义类似CreateUI
的方法以及其他一些方法,以某种通用形式在内部检索由自定义控件管理的数据。
这样,您将委托插件实现(您的自定义控件)负责正确创建UserControl并将其返回给调用者(您的页面)。 通过反射加载插件实现(类似这样):
Assembly pluginDLL = Assembly.Load(System.IO.File.ReadAllBytes(fullPath));
Type pluginType = pluginDLL.GetType(step.PluginClass);
IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
然后您可以在页面上加载控件:
pnlReportControl.Controls.Add(plugin.CreateUI());
答案 2 :(得分:-2)
尝试在page_load方法中替换以下代码
带有if (Page.IsPostBack) LoadUserControl();
的 if (!Page.IsPostBack)
LoadUserControl();