Help With "Object Reference Not Set"

5 posts, 0 answers
  1. Joshua
    Joshua avatar
    78 posts
    Member since:
    Sep 2008

    Posted 15 Mar 2010 Link to this post

    Okay, if I dynamically created a RadAjaxManager in a page's code-behind everything works fine.  I followed the same technique as: http://www.telerik.com/community/forums/aspnet-ajax/ajax/nullreferenceexception-in-radajaxmanager-ajaxsettings-addajaxsetting.aspx

    Then, I wanted to dynamically create the RadAjaxManager in a server control.  So I added:
            #region private properties  
              
            private RadAjaxManager _radAjaxManager = null;
            #endregion  
     
            protected override void OnInit(EventArgs e)  
            {  
                RadScriptManager scriptManager = new RadScriptManager();   
                Controls.Add(scriptManager);  
                  
                RadAjaxManager radAjaxManager = new RadAjaxManager();  
                radAjaxManager.ID = "radAjaxManager";  
                _radAjaxManager = radAjaxManager;  
                Controls.Add(radAjaxManager);  
                  
                base.OnInit(e);   
     
                scriptManager.Scripts.Add(new ScriptReference("Elevate.UI.Scripts.Search.js""Elevate"));  
            }  
     
            protected override void CreateChildControls()  
            {  
                RadAjaxLoadingPanel radAjaxLoadingPanel = new RadAjaxLoadingPanel();  
                radAjaxLoadingPanel.ID = "ajaxLoadingPanel";  
                radAjaxLoadingPanel.Skin = "Default";  
                Controls.Add(radAjaxLoadingPanel);  
     
                /* Child Controls Creation */ 
     
                _radAjaxManager.AjaxSettings.AddAjaxSetting(button1, simplePanel, radAjaxLoadingPanel);  
                _radAjaxManager.AjaxSettings.AddAjaxSetting(linkButton1, simplePanel, radAjaxLoadingPanel);  
                _radAjaxManager.AjaxSettings.AddAjaxSetting(lbMLS, simplePanel, radAjaxLoadingPanel);  
            } 

    As you can imagine, I get the dreaded NullReferenceException. 

    Obviously, I don't want to require the end-user to add a RadAjaxManager to the page manually or in the parent page's OnInit.  I want the control to be self-contained (i.e. adding the RadAjaxManager only when needed for the control).

    How do I do this?

    Thanks,
    Joshua
  2. Joshua
    Joshua avatar
    78 posts
    Member since:
    Sep 2008

    Posted 16 Mar 2010 Link to this post

    Can I please get some help on this?

    Thanks,
    Joshua
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Veli
    Admin
    Veli avatar
    2002 posts

    Posted 18 Mar 2010 Link to this post

    Hi Joshua,

    You can add RadAjaxManager and RadScriptManager to your page from user controls you develop. However, there are a couple of rules you need to follow tightly.

    These rules are related to RadAjaxManager. It has special requirements as to how it needs to be created and how AJAX settings are to be added. Particularly, RadAjaxManager needs to be created in the OnInit or Page_Init methods of the Page object. As you will be inserting the manager from a user control, you are left with OnInit.

    So, supposing you are subclassing, let's say, RadGrid. You have:

    public class Grid : RadGrid
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }
     
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }
    }

    Obviously, I will need the OnInit and OnLoad methods of the control overridden. Now, how do we insert RadAjaxManager to the page at latest before the end of the OnInit method of the Page? We need to subscribe for the OnInit event of the Page object:

    public class Grid : RadGrid
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.Init += new EventHandler(Page_Init);
        }
     
        void Page_Init(object sender, EventArgs e)
        {
            ScriptManager scriptManager = null;
            RadAjaxManager ajaxManager = null;
     
            foreach (Control control in Page.Form.Controls)
            {
                if (control is ScriptManager) scriptManager = (ScriptManager)control;
                if (control is RadAjaxManager) ajaxManager = (RadAjaxManager)control;
            }
     
            if (scriptManager == null)
            {
                scriptManager = new RadScriptManager { ID = "RadScriptManager1" };
                Page.Form.Controls.AddAt(0, scriptManager);
            }
     
            if (ajaxManager == null)
            {
                ajaxManager = new RadAjaxManager { ID = "RadAjaxManager1" };
                Page.Form.Controls.AddAt(1, ajaxManager);
            }
        }
     
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }
    }


    As you can see, in the attached Page.Init event handler, I check if I do not previously have RadScriptManager and RadAjaxManager created, and, if not, do create them.

    Now we need to add the AJAX settings for AJAX-enabling our server control. The RadAjaxManager's AjaxSettings should be added on Load event of either the page or the control. I use the control's OnLoad method:

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
     
        RadAjaxManager ajaxManager = RadAjaxManager.GetCurrent(Page);
        ajaxManager.AjaxSettings.AddAjaxSetting(this, this);
    }

    At this point, our server control is AJAX-enabled. When we add it on any page, no matter if the page contains a ScriptManager and an AjaxManager, the server control will work asynchronously.

    There is one last requirement though. Our most attentive readers will note that, as we are subscribing for the Page.Init event, my control needs to be added to the Page's controls collection pretty earlier in the page lifecycle. Otherwise, if Page.Init has passed by the time the server control is initialized, we do not get the managers added.

    Now this requirement may seem pretty strict for some. It implies that I can add my custom server control to the Page's Controls collection in no more than 2 ways:

    1. Declaratively through the markup:

    <my:Grid ID="Grid1" runat="server" AllowPaging="true" AllowSorting="true" PageSize="5">
    </my:Grid>

    That option may be sufficient for most control consumers, so this might be a sufficient reason to go for inserting script and AJAX managers through server controls.

    2. Programmatically, in the overriden OnInit method of the page and before  calling base.OnInit(e):

    protected override void OnInit(EventArgs e)
    {
        Grid g = new Grid();
        g.ID = "Grid1";
        g.AllowPaging = true;
        g.PageSize = 5;
        Form.Controls.Add(g);
     
        base.OnInit(e);
    }

    The second approach is trickier. It says that you can add the control dynamically, but you need to do it only in OnInit(), and only before calling base.OnInit(). The reason? We subscribe to the Page.Init event from the control, remember? We need to make sure Page.Init fires after the control is loaded. Hence, we need to load the control before base.OnInit(e) which will cause the Page object to fire the Init event.

    I hope this makes sense. Sample page with custom server control is attached for those who want to try it out.

    Sincerely yours,
    Veli
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  5. JD
    JD avatar
    22 posts
    Member since:
    Jul 2013

    Posted 10 Feb 2014 in reply to Veli Link to this post

    Veli,

    Thanks for your comprehensive answer to this.  My problem is, the entire userControl stack is being created dynamically.  The aspx page places the user control (.cs ONLY, no .ascx) in the Controls collection during its Page_Init.  This means that I can't subscribe to Page_Init from my userControl because the event has passed by the time its own OnInit happens.  I don't have control of the aspx page, only the userControl and I need ajaxy elements in it, requiring a RadAjaxManager.

    Is this possible?

    Thanks,
    JD
  6. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 13 Feb 2014 Link to this post

    Hi Justyn,

    Ajaxifying  controls that are positioned within a user controls works somewhat differently from the scenario when they are loaded directly on a web form. In your case, you need to move the RadAjaxManager control to the mentioned UC  class, create it there and add it to the Controls collection  as follows:
    private RadAjaxManager _ajaxManager;
      
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
      
        SetUpAjaxManagerOnPage();
      
        EnsureChildControls();
    }
      
      
    protected void SetUpAjaxManagerOnPage()
    {
        RadAjaxManager currentAjaxManager = RadAjaxManager.GetCurrent(Page);
      
        if (currentAjaxManager == null)
        {
            Page.Form.Controls.AddAt(0, AjaxManager);
            Page.Items.Add(typeof(RadAjaxManager), AjaxManager);
        }
    }
      
    protected virtual RadAjaxManager AjaxManager
    {
        get
        {
            if (_ajaxManager == null)
            {
                _ajaxManager = RadAjaxManager.GetCurrent(Page);
      
                if (_ajaxManager == null)
                {
                    _ajaxManager = new RadAjaxManager() { ID = "RadAjaxManager1" };
                }
            }
      
            return _ajaxManager;
        }
    }

    Then in the OnLoad event get the RadAjaxManager and add programmatic settings:
    RadAjaxManager _manager = RadAjaxManager.GetCurrent(Page);

    I hope this helps.

    Regards,
    Maria Ilieva
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017