C# 使用 LoadControl 方法动态加载 UserControl(类型,对象 [])

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/450431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 03:51:40  来源:igfitidea点击:

Dynamically Loading a UserControl with LoadControl Method (Type, object[])

c#asp.net

提问by abjbhat

I'm trying to return the html representation of a user/server control through a page method. It works when I call the overload which takes the virtual path to the user control, but not when I try to call the overload which takes a type. The sample code is below. Any suggestions?

我正在尝试通过页面方法返回用户/服务器控件的 html 表示。当我调用采用用户控件的虚拟路径的重载时,它起作用,但当我尝试调用采用类型的重载时则不起作用。示例代码如下。有什么建议?

[WebMethod]
public static string LoadAlternates(string productId, string pnlId)
{
    object[] parameters = new object[] { pnlId, productId };
    return ControlAsString(typeof(PopupControl), parameters);
}

private static string ControlAsString(Type controlType, object[] parameters)
{
    Page page = new Page();
    UserControl controlToLoad;
    /*
     *calling load control with the type results in the 
     *stringwriter returning an empty string
    */

    controlToLoad = page.LoadControl(controlType, parameters) as UserControl;
    /*
     *However, calling LoadControl with the following overload
     *gives the correct result, ie the string rep. of the control.
    */
     controlToLoad = page.LoadControl(@"~/RepeaterSamples/PopupControl.ascx") as UserControl;

    //some more code, then this... 
    page.Controls.Add(controlToLoad);

    StringWriter sw = new StringWriter();
    HttpContext.Current.Server.Execute(page, sw, false);
    return sw.ToString();
}

Any ideas why this StringWriter would return an empty string? I should point out that all the "page" lifecycle execute correctly irrespective of the method chosen to call LoadControl.

任何想法为什么这个 StringWriter 会返回一个空字符串?我应该指出,无论选择调用 LoadControl 的方法如何,所有“页面”生命周期都会正确执行。

Wanted to add - I haveto use the LoadControl(Type, object[])overload. :-(

想补充 - 我必须使用LoadControl(Type, object[])重载。:-(

回答by lomaxx

On the MSDN page for LoadControlthere is this comment at the bottom:

LoadControlMSDN 页面上,底部有这条评论:

Description
A page that loads a user control using the Page.LoadControl(Type, Object[]) does not seem to create its children added in the ascx file. Using Page.LoadControl(String) works as expected.

Comments
Thank you for submitting this issue. We're investigating and will provide an update on status when we have more information.

-The Web Platform & Tools Team
Posted by Microsoft on 8/06/2005 at 11:08 AM
This is by-design since the type "TestUC" is actually the base type used by the partial class, it does not contain the proper code to instantiate TextBox1 reference, which is actually defined in the derived type. There are two workarounds: 1. Use LoadControl("TestControl.ascx"), for all practical, this behaves identically to LoadControl(type) but it instantiates the derived type, which knows how to instantiate TextBox1. 2. Use a single file page and adds <%@ Reference %> directive to the page to reference the user control, and assign a classname to the ascx page. Then it's safe to use LoadControl(type)

Thanks for reporting the issue.
Web Platform and Tools Team. Posted by Microsoft on 14/06/2005 at 6:31 PM

说明
使用 Page.LoadControl(Type, Object[]) 加载用户控件的页面似乎不会创建其添加到 ascx 文件中的子项。使用 Page.LoadControl(String) 可以按预期工作。

评论
感谢您提交此问题。我们正在调查,并会在获得更多信息时提供状态更新。


-Microsoft 于 2005 年 8 月 6 日上午 11:08 发布的Web 平台和工具团队
这是故意设计的,因为类型“TestUC”实际上是分部类使用的基类型,它不包含正确的代码实例化 TextBox1 引用,它实际上是在派生类型中定义的。有两种解决方法: 1. 使用 LoadControl("TestControl.ascx"),实际上,这与 LoadControl(type) 的行为相同,但它实例化派生类型,它知道如何实例化 TextBox1。2. 使用单个文件页面并在页面中添加<%@ Reference %> 指令以引用用户控件,并为ascx 页面分配一个类名。那么就可以安全地使用 LoadControl(type)

感谢您报告问题。
Web 平台和工具团队。由 Microsoft 于 2005 年 14 月 6 日下午 6:31 发布

回答by Steven Robbins

That overload instantiates the base class, but doesn't instantiate any of the controls on it, so it doesn't work.

该重载实例化基类,但不实例化其上的任何控件,因此它不起作用。

I did a quick blog poston a workaround for passing parameters if you're interested.

如果您有兴趣,我写了一篇关于传递参数的解决方法的快速博客文章

回答by Andrew Hare

If you want to have the control completely rendered one way to do this is to instantiate the control as you are now with LoadControland then temporarily add it to the control collection of another control or the page itself. This will initialize the life-cycle for that control and cause all of the proper events to be raised. Once you have done this then you can get the rendered HTML or whatever you need from it.

如果您想让控件完全呈现,一种方法是像现在一样实例化控件LoadControl,然后将它临时添加到另一个控件的控件集合或页面本身。这将初始化该控件的生命周期并引发所有正确的事件。完成此操作后,您可以从中获取呈现的 HTML 或任何您需要的内容。

Yes, this is a hack but it will work in a pinch.

是的,这是一个黑客,但它会在紧要关头工作。