views:

1305

answers:

3

I am trying to render a user control into a string. The application is set up to enable user to use tokens and user controls are rendered where the tokens are found.

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();

That code renders the control but none of the events called in the Page_Load of the control are firing. There's a Repeater in the control needs to fire.

+2  A: 

You would need to attach the control to a Page by adding it to a Controls collection of the Page or a Control on the page. This won't solve all of your problems unless you do something to explicitly disable rendering during the normal page render event.

cfeduke
+4  A: 

I've been using the following code provided by Scott Guthrie in his blog for quite some time:

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();
    }
}

The object data parameter, enables dynamic loading of data into the user control, and can be used to inject more than one variable into the control via an array or somethin similar.

This code will fire all the normal events in the control.

You can read more about it here

Regards Jesper Hauge

Hauge
That HttpContext.Current.Server.Execute(pageHolder, result, false); is money
Jon Smock
Just what I was looking for! Thanks
Dead account
A: 

I took Hauge's/ Scott Guthrie's method above and tweaked it so that you don't need to use reflection, or modify a UserControl to implement any special interface. The key was I added a strongly typed callback that the RenderView method above calls, instead of doing reflection.

I blogged the helper method and usage here

HTH, Jon

Jon Kragh