views:

99

answers:

1

I need to configure a property of a custom control I wrote, specifically before the control calls OnInit. If I assign it as part of the ASPX file, it naturally works, but if I instead move the assignment to different parts of the code-behind, it will throw an error for having an empty and invalid value. The following is what it looks like when functional in the ASPX page.

<MyCustomControls:SingleCascadeLookupMulti FilterString="Seventh" FilterByStatus="true" ControlMode="New" FieldName="Speciality" EnableViewState="true" ID="sclmDocuments" runat="server" TemplateName="SingleCascadeLookupMulti" />

The property in question is FilterString, which is just a simple string. It should be noted as well that the FieldName property (inheritted from the control's base class "BaseFieldControl") would also throw an error if it is not initialized, but if I set FieldName in the code behind's OnInit method, it works correctly. FilterString is not so, it won't actually be assigned. So I know that some methods for certain properties will work for setting the property's value, but it won't always work. I tried placing it in OnPreInit as well, to no avail.

I am taking a dynamic assignment approach because the functionality of this page needs to be replicated for a number of different lists, and the FilterString and FieldName properties will differ in every case. Rather than write half a dozen mostly-identical aspx pages all with the same code behind but differing just in what those two properties are, I figured it would be wiser to use the page's query string and some derived parameters to set those properties dynamically. As such, what methods are available to accomplish this task?

+1  A: 

One method I've used to do this is to create a constructor in the control that takes the parameters I need to set (in your case FilterString). I then use the following function to load the control dynamically, passing it the parameters:

protected UserControl LoadControl(string UserControlPath, params object[] constructorParameters)
{
    List<System.Type> constParamTypes = new List<System.Type>();
    foreach (object constParam in constructorParameters)
    {
        constParamTypes.Add(constParam.GetType());
    }

    UserControl ctl = Page.LoadControl(UserControlPath) as UserControl;

    // Find the relevant constructor
    ConstructorInfo constructor = ctl.GetType().BaseType.GetConstructor(constParamTypes.ToArray());

    //And then call the relevant constructor


      if (constructor == null)
        {
            throw new MemberAccessException("The requested constructor was not found on : " + ctl.GetType().BaseType.ToString());
        }
        else
        {
            constructor.Invoke(ctl, constructorParameters);
        }

        // Finally return the fully initialized UC
        return ctl;
    }

and call the method like this:

Control ctlToAdd = this.LoadControl("UserControls/MyControl.ascx", Parameter1, "Parameter2");
        MyDiv.Controls.Add(ctlToAdd);
derek
I'm terribly sorry, this was a mistake on my part. My incorrect tagging implied this was a user control, but this is a custom control (so no ASCX file). This probably changes your answer. I'm currently testing an approach inspired by the current one, though. I'll let you know how it goes.
ccomet
Well, with or without the ASCX file, by configuring it in the same methods described here and adding it via Controls.AddAt, I've got it working perfectly. It actually worked better than I expected, too. Thanks for the help!
ccomet