将用户控件以编程方式加载到HTML文本编写器中

6

我正在尝试将用户控件渲染为字符串。该应用程序已设置为允许用户使用令牌,用户控件将在发现令牌的位置呈现。

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter writer = new HtmlTextWriter(sw);

Control uc = LoadControl("~/includes/HomepageNews.ascx");
uc.RenderControl(writer);
return sb.ToString();

该代码可以呈现控件,但是在控件的Page_Load事件中调用的任何事件都没有触发。控件中有一个Repeater需要触发。

3个回答

13

我已经使用Scott Guthrie在他的博客中提供的以下代码有一段时间了:

public class ViewManager
{
    public static string RenderView(string path, object data)
    {
        Page pageHolder = new Page();
        UserControl viewControl = (UserControl) pageHolder.LoadControl(path);

        if (data != null)
        {
            Type viewControlType = viewControl.GetType();
            FieldInfo field = viewControlType.GetField("Data");
            if (field != null)
            {
                field.SetValue(viewControl, data);
            }
            else
            {
                throw new Exception("ViewFile: " + path + "has no data property");
            }
        }

        pageHolder.Controls.Add(viewControl);
        StringWriter result = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, result, false);
        return result.ToString();
    }
}

object data参数使得数据可以动态加载到用户控件中,并且可以使用数组或者类似的方式将多个变量注入到控件中。

这段代码会触发控件中所有正常的事件。

您可以在这里阅读更多信息。

敬礼,Jesper Hauge


那个 HttpContext.Current.Server.Execute(pageHolder, result, false); 是金钱。 - Jon Smock
当您尝试在UserControl内部使用async/await时,此方法不起作用。 - Silvos

2

您需要将控件添加到页面的Controls集合或页面上的控件中,以使其与页面相关联。但这并不能解决所有问题,除非您采取某些措施在正常的页面渲染事件期间明确禁用渲染。


1
我采用了Hauge/Scott Guthrie上面的方法,并对其进行了调整,以便您无需使用反射或修改UserControl来实现任何特殊接口。关键是我添加了一个强类型回调,RenderView方法会调用它,而不是进行反射。
我在博客中记录了这个帮助方法和用法here
希望有所帮助, Jon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接