Question

I found this extremely useful article on creating instances of ASP.NET UserControls in .ASHX Handlers by Scott Guthrie.

Unfortunately I now have a requirement now where I need to create an instance of a UserControl which has a dependency on the parent page. This being the case, I can't use the same method to create the UserControl.

Can anyone suggest how I might go about this? What is involved in creating an instance of the Parent page and then getting the contents of the UserControl it contains?

Just for reference & to be specific on the type of depenendency I'm dealing with, the UserControl is a panel that exists on a main Factsheet page. Depending on the user's configuration preferences, different controls are dynamically generated in the Factsheet's base class FactsheetBuilderPage, and included on the page.

The UserControl has properties, such as:

public DateTime EffectiveDate
{
    get
    {
        return ((FactsheetBuilderPage)this.Page).EffectiveDate;
    }
}

public Site ConfiguredSite
{
    get { return ((FactsheetBuilderPage)this.Page).SiteConfiguration; }
}

public ConfiguredFund Fund
{
    get
    {
        return ((FactsheetBuilderPage)this.Page).Fund;
    }
}

which reference the FactsheetBuilderPage class, which means I need to create a FactsheetBuilderPage class for it to reference.

Ideally I'd be able to resolve this issue without having to modify the existing code base, because refactoring this will be a real pain!!

Thanks guys

Dave

Was it helpful?

Solution 2

Ok, so the solution turned out to be changing the UserControl's properties to be automatic, instead of just having a getter that referrs to the parent page.

public ConfiguredFund Fund { get; set; }

public DateTime EffectiveDate { get; set; }

public Site ConfiguredSite { get; set; }

Now it means that I have to explicitely assign values to these properties when the user control is being instantiated. This allows me to create an instance of this UserControl anywhere without the need for the parent page, as long as I can supply its required data.

then in my Handler, create an instance of the UserControl and assign the properties it needs:

private MyUserControl GetUserControl(int id)
{
    MyUserControl myUc = GetUserControl("Controls/MyUserControl.ascx");

    myUc.Fund = new ConfiguredFund(id);
    myUc.EffectiveDate = DateTime.Now;
    myUc.ConfiguredSite = siteManager.GetSiteById(2);

    return myUc;
}

then to get the rendered html, I use a slightly modified version of Scott Guthrie's code:

public static string RenderView(MyUserControl viewControl, object data)
{
    Page pageHolder = new Page();

    if (data != null)
    {
        Type viewControlType = viewControl.GetType();
        FieldInfo field = viewControlType.GetField("Data");

        if (field != null)
        {
            field.SetValue(viewControl, data);
        }
        else
        {
            throw new Exception("View file doesn't have a public Data property");
        }
    }

    pageHolder.Controls.Add(viewControl);

    StringWriter output = new StringWriter();
    HttpContext.Current.Server.Execute(pageHolder, output, false);

    return output.ToString();
}

Thanks Guys

Dave

OTHER TIPS

You walked into this one, I'm afraid. If you're going to make a user control that is dependent on its page, then why is it separate? A user control is used to create modularity. They are not supposed to be dependent on the page.

That said, what is the dependence? Since you obviously don't want the page, then maybe you can provide what is needed without the page.

You can create and execute a page by a couple of methods. One is to use the BuildManager class to instantiate a page, like so:

Page page = BuildManager.CreateInstanceFromVirtualPath("/my/app/page.aspx", typeof(MyPageClass) ) as Page;

But if you need your page to execute in the current request context, try it this way:

Page page = new MyPageClass();  
page.AppRelativeVirtualPath = 
         context.Request.AppRelativeCurrentExecutionFilePath; 
page.ProcessRequest(context);

This is of course courtesy of Rick Strahl.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top