I am working on a large scale web application with a nested master page hierarchy. What I am trying to do is server side ajaxification. In other words, i want the same functionality as a ScirptManagerProxy, only not in the markup, but via a function that I will store in the Page's base class. The master page that contains the script manager is 3 levels up from the current master page that my content page is using. I've tried the RadAjaxManager.GetCurrent(Page) method, but since it lives so far down the master page chain, IT hasn't been created yet. I have created a function that will crawl back through the nesting to find me the master page i am looking for. I have also created a public property on the master page to expose the ajax manager.
Here's the root master page code behind:
public partial class Shell : MasterPage |
{ |
public RadAjaxManager AjaxManager |
{ |
get { return ajaxMgr; } |
} |
} |
Here's what my current layout looks like:
Shell.master
--> LeftSideAndContent.master
--> LeftNavigationAndContent.master
--> ContentPage.aspx
After doing some research (using Reflector), i found that master pages are actually created in the getter of Page.Master, so simply casting ContentPage's Master as (Shell) doesn't work, and returns a null reference of the script Manger. The master can be referenced correctly by using this.Master.Master.Master, but this is bad design, as it will break if our layout adds or subtracts layout master pages. To alleviate this problem, I created the following generic function on my content page's base class:
public abstract class ContentPageBase : System.Web.UI.Page |
{ |
public static T FindMasterPage<T>(Page page) where T : MasterPage |
{ |
Type type = typeof(T); |
MasterPage master = page.Master; |
while (master != null) |
{ |
if (master.GetType().BaseType == type) |
{ |
break; |
} |
master = master.Master; |
} |
return (T)master; |
} |
} |
What this allows me to do is is get a hook to the actual RadAjaxManager that exists up the chain in the following way:
AjaxSetting setting = new AjaxSetting(uxCategoryGrid.ClientID); |
setting.UpdatedControls.Add(new AjaxUpdatedControl(uxCategoryGrid.ClientID, "")); |
ContentPageBase.FindMasterPage<Shell>(this).AjaxManager.AjaxSettings.Add(setting); |
After all this, I am still having an issue with the loading panel not popping up when I muck with the grid. Am I missing something here? I know that the master Page_Load fires AFTER the content Page_Load, so could the master page be annihilating the controls of the AjaxManager even after it gets hydrated in the function?
Ideally, what I am looking for is the easiest way to accomplish the following:
public partial class ContentPage : ContentPageBase |
{ |
protected void Page_Load(object sender, EventArgs e) |
{ |
this.Ajaxify(uxCategoryGrid); |
} |
} |
Any help will be appreciated.
Paul