Dynamicically Cast Page.LoadControl in C #

I am writing some custom controls for the first time and I am wondering if there is a way to clean up some of my code. (If you'd like to know more about what I'm working on, see this question .)

I have a class BaseControl

that basically parses some XML data and then, depending on what's in that data, calls the appropriate one UserControl

and sends the data along 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 is not the code I wrote, this is just an example of where I could go. What I would like to do is something more:

...
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 up this mess?

+3


source to share


2 answers


Interface

You can have all of the controls that implement the common interface and drop onto it.

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 the online IDE.

Base class



You can also use an abstract base class and give this type the same results. You will need to use a base class that inherits from UserControl

. This will avoid having two object references (like in my example above), because it can be distinguished before UserControl

.

The above example:

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

      

If the logic is different for each type of control, then you will probably need to apply to each specific type (basically a big if / else block) and handle each control separately. In other words, if you need to do different things based on the type of the control, you need logic that recognizes the type.

For completeness, I mentioned that you can also use DLR , but I would suggest against that. You would give up compile-time type safety and performance to reduce small code.

+5


source


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



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

      

0


source







All Articles