views:

343

answers:

2

Hello!

I have been looking around on the web and found some articles about the topic, but i still can't figure out the difference between them. I have the code show below, if i inherit from a CompositeControl it works perfectly but not if i inherit from a WebControl. (They both render the code, but only the CompositeControl handles the event)

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace TestLibrary
{
    public class TemplateControl : CompositeControl
    {
        TextBox txtName = new TextBox();
        TextBox txtEmail = new TextBox();
        Button btnSend = new Button();

        private void SetValues()
        {
            btnSend.Text = "Skicka";
        }

        protected override void CreateChildControls()
        {
            SetValues();

            this.Controls.Add(new LiteralControl("Namn: "));
            this.Controls.Add(txtName);
            this.Controls.Add(new LiteralControl("<br />"));
            this.Controls.Add(new LiteralControl("Email: "));
            this.Controls.Add(txtEmail);
            this.Controls.Add(new LiteralControl("<br />"));
            btnSend.Command += new CommandEventHandler(btnSend_Command);
            this.Controls.Add(btnSend);
        }

        void btnSend_Command(object sender, CommandEventArgs e)
        {
            this.Page.Response.Write("Du har nu klickat på skicka-knappen! <br /><br />");                
        }
    }
}

So when i click the button and the control is rendered as a WebControl, nothing happens. But if i change the WebControl to a CompositeControl, the text is printed out. Why? Whats the difference between the WebControl and the CompositeControl?

A: 

http://stackoverflow.com/questions/71092/what-is-the-difference-between-usercontrol-webcontrol-renderedcontrol-and-compo

Why does one behave differently than the other? Because they're different types. If they were the same type there wouldn't be two of them.

Will
+3  A: 

CompositeControls implement INamingContainer while WebControls don't.

There are more differences between the two, but that's why the composite control can route the event to its child but the web control can't. You can see this by changing your class declaration to this:

public class TemplateControl : WebControl, INamingContainer

Voila, your button event will now be handled!

INamingContainer is just a marker interface that tells ASP.NET a control contains children that may need to be accessed independently of their parent control, so child controls get those extra pretty ids we ASP.NET developers have come to know and love (e.g., ctl00$ctl00).

If the WebControl doesn't implement INamingContainer, the child's id isn't guaranteed to be unique, so the parent can't reliably identify it and can't forward it events.

Jeff Sternal
Perfect, thanks!
Patrick