Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Cast Page.LoadControl in C#

Tags:

c#

.net

asp.net

I'm writing some user controls for the first time and I'm wondering if there's a way I can clean up some of my code. (If you'd like more background on what I'm working on, see this question.)

I have a BaseControl class that, basically, parses some XML data and then, depending on what is contained in that data, calls the appropriate UserControl and sends the data on its way. Here's an example:

public partial class BaseControl : User Control
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ... //code that parses the data
        var renewalDef = effort.Attributes["renewal_def"].Value;
        var effortNumber = effort.Attributes["renewal_effort_number"].Value;
        if (effortNumber == "1")
        {
            var effortControl = (NAVLEffort1) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort1.ascx");
            effortControl.transactionData = transaction; //'transaction' is a Hashtable object
            HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
        }
        if (effortNumber == "2")
        {
            var effortControl = (NAVLEffort2) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort2.ascx");
            effortControl.transactionData = transaction; //'transaction' is a Hashtable object
            HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
        }
        if (effortNumber == "3")
        {
            var effortControl = (NAVLEffort3) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort3.ascx");
            effortControl.transactionData = transaction; //'transaction' is a Hashtable object
            HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
        }
        // and so on...
    }
}

This isn't the actual code I've written, it's just an example of where I could be headed. What I'd like to do is something more like this:

...
var effortControlFileString = string.Format("~/NAVLSeriesControls/{0}Effort{1}.ascx", renewalDef, effortNumber);
var effortControl = (renewalDef + "Effort" + effortNumber) Page.LoadControl(effortControlFileString);
effortControl.transactionData = transaction;
HtmlContent.Controls.Add(effortControl)
...

Any ideas how I can clean this mess up?

like image 328
Spencer R Avatar asked Nov 08 '25 19:11

Spencer R


2 Answers

Interface

You could have all controls implement a common interface and cast to that.

public interface IMyInterface
{
    object TransactionData
    {
       get;
       set;
    }
}

Control effortControl = Page.LoadControl(path);
HtmlContent.Controls.Add(effortControl);

IMyInterface obj = (IMyInterface)effortControl;
obj.TransactionData = transaction;

See this working example in an online IDE.

Base Class

You could also use an abstract base class and cast to that type with the same results. You will need to use a base class which inherits from UserControl. This would avoid having two object references (as in my example above) because it can be cast to UserControl.

The example above becomes:

MyCustomControlType c = (MyCustomControlType)Page.LoadControl(path);
HtmlContent.Controls.Add(c);
c.TransactionData = transaction;

If the logic for each control type is different, then you will probably need to cast to each specific type (basically a big if/else block) and deal with each control individually. In other words, if you need to perform different actions based on the type of the control, you will need logic that is type-aware.

For completeness sake I will mention that you could also use the DLR but I would suggest against it. You would be giving up compile-time type safety and performance to reduce a little code.

like image 174
Tim M. Avatar answered Nov 10 '25 09:11

Tim M.


you can create an interface and add your control to html page. ex:

private Control _contentControl;

_contentControl = Page.LoadControl("~/Administration/Projects/UserControls/" + controlName);
        ((IEditProjectControl)_contentControl).ProjectId = ProjectId;
        plhContent.Controls.Clear();
        plhContent.Controls.Add( _contentControl );
        _contentControl.ID = "ctlContent";
        Image2.Visible = ((IEditProjectControl)_contentControl).ShowSaveButton;
        SaveButton.Visible = ((IEditProjectControl)_contentControl).ShowSaveButton;
        ((IEditProjectControl)_contentControl).Initialize();
like image 43
shary.sharath Avatar answered Nov 10 '25 08:11

shary.sharath



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!