Wrox Programmer Forums
|
ASP.NET 1.0 and 1.1 Professional For advanced ASP.NET 1.x coders. Beginning-level questions will be redirected to other forums. NOT for "classic" ASP 3 or the newer ASP.NET 2.0 and 3.5
Welcome to the p2p.wrox.com Forums.

You are currently viewing the ASP.NET 1.0 and 1.1 Professional section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old December 18th, 2003, 01:53 AM
Registered User
 
Join Date: Jun 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default User controls and event handler binding

Hi,

I'm trying to use a simple user control to create a template for my site. I then want to use this control to nest my page's content within it. I can nest all controls I've tried so far and it works well. However, as soon as I add an event handler to any of those nested controls, the page loads a NullReference error message.

I suspect that event handler binding takes place before the user control that contains the nested control loads, and therefore before the nested controls are instantiated, leaving the nested controls null at handler binding time (when InitializeComponent is called)

I'd like to modify my user control to avoid this kind of problem if possible... anyone have any ideas on how this might be done?

Here's the code I have for the user control (template.ascx) so far.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <HEAD>
        <title>
            <%=this.Title%>
        </title>
        <script runat="server">
            /// <summary>
            /// Insert the body the user provided in our body placeholder.
            /// </summary>
            protected override void CreateChildControls()
            {
                // insert the main content body if available
                if( null != Body )
                    Body.InstantiateIn( bodycontainer );
            }
        </script>
    </HEAD>
    <body>
        <div>Header</div>
        <div><asp:placeholder id="bodycontainer" runat="server" /></div>
        <div>Footer</div>
    </body>
</HTML>
And it's code behind
Code:
namespace Testing
{
    using System;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;

    /// <summary>
    ///    Summary description for template.
    /// </summary>
    [ParseChildren(true)]
    public class template : UserControl, INamingContainer
    {
        protected System.Web.UI.WebControls.PlaceHolder bodycontainer;

        /// <summary>
        /// The main content template.
        /// </summary>
        private ITemplate main;
        /// <summary>
        /// The name of the page.
        /// </summary>
        private string title;
        /// <summary>
        /// The main content template.
        /// </summary>
        public ITemplate Body
        {
            get { return this.main; }
            set { this.main = value; }
        }
        /// <summary>
        /// The name of the page.
        /// </summary>
        public string Title
        {
            get { return this.title; }
            set { this.title = value; }
        }

        private void Page_Load(object sender, System.EventArgs e)
        {
            // Put user code to initialize the page here
        }

        protected override void CreateChildControls()
        {
            // insert the main content body if available
            if( null != Body )
            {
                Trace.Warn("Instantiating Template");
                Body.InstantiateIn(bodycontainer);
            }
        }


        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        ///        Required method for Designer support - do not modify
        ///        the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.Load += new System.EventHandler(this.Page_Load);

        }
        #endregion

    }
}
Here's the page that uses the user control
Code:
<%@ Register TagPrefix="nm" TagName="template" Src="template.ascx"%>
<nm:template id="template" title="Example of Page Templating" runat="server">
    <body>
        <form id="tester_form" runat="server">
            <asp:Label id="Label1" runat="server">Label</asp:Label>
            <asp:Button id="Button2" runat="server" Text="Button" OnClick="Button2_Click"></asp:Button>
        </form>
    </body>
</nm:template>
And it's code behind
Code:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Testing
{
    /// <summary>
    /// Summary description for test.
    /// </summary>
    public class test : System.Web.UI.Page
    {
        protected System.Web.UI.WebControls.Button Button2;
        protected System.Web.UI.WebControls.Label Label1;

        private void Page_Load(object sender, System.EventArgs e)
        {
            // Put user code to initialize the page here
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {    
            Trace.Warn("this.Button2 " + (this.Button2 == null ? "=" : "!") + "= null");    //Returns null
            Trace.Warn("Button2 " + (Button2 == null ? "=" : "!") + "= null");        //Returns null
            //this.Button2.Click += new System.EventHandler(this.Button2_Click);        //Throws a NullException
            this.Load += new System.EventHandler(this.Page_Load);

        }
        #endregion

        public void Button2_Click(object sender, System.EventArgs e)
        {
            this.Label1.Text = "Clicked!";
            Trace.Warn("Clicked");
        }
    }
}
 
Old December 18th, 2003, 10:52 AM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

I'm not positive at what point in the page lifecycle the controls from the markup are parsed and where the parsing occurs relative to "InitializeComponent". Is it possible that InitializeComponent happens before the parsing? If so then your control's will most definately return null at that point.

If you are just getting started building a "templated" web application, take a look here, it might be of some use to you.

Peter
------------------------------------------------------
Work smarter, not harder.





Similar Threads
Thread Thread Starter Forum Replies Last Post
HOW TO ADD AN EVENT HANDLER pallone .NET Framework 2.0 10 September 16th, 2008 12:28 PM
Event handler samir_katore Pro VB 6 6 June 8th, 2006 01:22 PM
Event handler problem carro123 Javascript How-To 1 May 20th, 2005 03:30 PM
late binding, how to I create an event handler? grom VB How-To 3 November 16th, 2004 02:33 AM
late binding, how to I create an event handler? grom Pro VB.NET 2002/2003 0 October 8th, 2004 03:42 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.