Wednesday, April 13, 2011

Dynamically adding user controls registered in web.config‏

So I'm working on a project that has all its user controls registered in its web.config file (which seems very clean and tidy)

So far so good (here comes the problem) however I'm trying to dynamically create and add user controls to a page. These user controls fire events that need handling.

Ordinarily that wouldn't be a problem: You just register the control in the page, load the control, cast it to the correct type, and assign the event handlers, add it to the page, sit back and let the magic happen, easy peasy.

But I can't reference the control's type when the control is registered in the web.config, which means no cast, which means no event handling!

Weirdly you can reference the type if you add the usercontrol to the page at design time!

There must be a way round this (without having to register the control on the page, or add a control at design time), what on earth am I missing?

From stackoverflow
  • By saying : "you can reference the type if you add the usercontrol to the page at design time"

    Do you mean it adds an <%@ Register %> Directive at the top of the page ?

    Or maybe, it adds a using / Imports (depending on you using c# / vb.net) clause in your source document ?

    Because, to be able to cast to your control type, you normally need to import the namespace in the codebind. Maybe this is just what is missing.

    Wilfred Knievel : No that's the weird thing, the registration is done in the web.config () so there isn't any need for <%@ Register %> directive on the page. If you drag your user control on the page the everything just starts working (doesn't add a <%@ Register %> or an includes)
  • The <controls> section in web.config and the <%@ Register %> directive are the same thing (with the small exception that entries in web.config apply to the whole application). They allow you to add design-time controls to a web form.

    If you want to add controls to a page dynamically, use the LoadControl function to get an instance of your control. Given a control with a class name of "Header", the following will load a control, set a property, and add the control to the form named, "form1":

        Dim head As Header = LoadControl("~/Controls/Header.ascx")
        head.Text = "Some text..."
        Me.form1.Controls.Add(head)
    
    Wilfred Knievel : That's exactly what I expected, but I get "The type or namespace name 'Header' could not be found (are you missing a using directive or an assembly reference?)" (the weird thing is if I add the tag for a header control to the page [just the ] it will work fine!)
  • It's been a while, but I think I've seen this type of behavior in ASP.NET when a project is a Web Site and not the Web Application. As far as I remember, the Web Site compiles each page into its own assembly and with no common name space and regardless of config requires the <%@ Register %> directive. If you don't, you get the exact error of missing an assembly reference.

    I would have to test to be sure...

    Martin : You're right about the website compiling each page into it's own assembly. If you register controls in the web.config, it should be fine. However, maybe the controls have to be defined in a separate assembly for it to work. At work, we use telerik's controls in a website project and it works fine.
    Wilfred Knievel : You're absolutely right, just did a quick test and it worked fine in a Web application and failed miserably in a website. Thanks for that!
  • I am trying to do the same thing also. I want to be able to do something like:

    Dim head As Header = LoadControl("MyHeaderTagPrefix", "MyHeaderTagName")
    head.Text = "Some text..."
    Me.form1.Controls.Add(head)

    I would expect to be able to retriev the control using those 2 values at runtime (aka Dynamically).

    Any ideas?

0 comments:

Post a Comment