Here is screen shot of my implementation:
There are a few important things that goes on in this code. However, before I explain that, I will show you the JavaScript that I wrote to handle the client events in "myUserControl.ascx". Here is the JavaScript code: From my user control "myUserControl.ascx": <telerik:RadCodeBlock ID="RadCodeBlock1" runat="server"> <script type="text/javascript"> <!-- var isAjaxActive; var tabValue; function onContextMenuItemSelected(sender, e) { if (!isAjaxActive) { //Get context menu item ("NEW", "EDIT" or whatever the Value parameter is.). var contextMenuItem = e.get_item().get_value(); var ajaxManager = $find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>"); //Must always follow this standard when making ajax calls - "[name of caller]*..." ajaxManager.ajaxRequest("MenuTab" + "*" + tabValue + "*" + contextMenuItem); } } function showContextMenu(sender, e) { //Get the menu_id of the clicked tab which is stored in the value field. tabValue = e.get_tab().get_value(); var menu = $find("<%= rcmMenuTab.ClientID %>"); if (menu != null) { var rawEvent = e.get_domEvent().rawEvent; menu.show(rawEvent); $telerik.cancelRawEvent(rawEvent); } } function RequestStart(sender, args) { if (isAjaxActive) { args.set_cancel(true); } else { isAjaxActive = true; } } function ResponseEnd(sender, args) { isAjaxActive = false; } --> </script> </telerik:RadCodeBlock> And here is the inline definitions for my RadTabStrip and RadContextMenu. From my user control "myUserControl.ascx": <div id="menuTab"> <telerik:RadTabStrip runat="server" ID="rtsMenuTab" CausesValidation="false" EnableEmbeddedSkins="false" Skin="LuminoTabStrip" SelectedIndex="0" DataSourceID="odsMenu" DataFieldID="menu_prioritet" DataFieldParentID="parent_id" DataValueField="menu_id" EnableViewState="false" EnableSubLevelStyles="false" Orientation="HorizontalTop" OnDataBound="rtsMenuTab_DataBound" DataTextField="menu_tekst" OnTabDataBound="rtsMenuTab_TabDataBound" OnClientContextMenu="showContextMenu"> </telerik:RadTabStrip> <telerik:RadContextMenu ID="rcmMenuTab" runat="server" EnableRoundedCorners="true" EnableShadows="true" OnClientItemClicked="onContextMenuItemSelected"> <Items> <telerik:RadMenuItem Text="<%$ Resources: Resource, lnkNyMeny %>" Value="NEW" ImageUrl="~/images/page_add.png" /> <telerik:RadMenuItem Text="<%$ Resources: Resource, btnEditMenu %>" Value="EDIT" ImageUrl="~/images/page_edit.png" /> </Items> </telerik:RadContextMenu> </div> As you can see from this code, I make a call to the JavaScript "showContextMenu" when the user right-clicks in the RadTabStrip (defined as OnClientContextMenu="showContextMenu" in the RadTabStrip). The JavaScript "showContextMenu", first gets the menu_id of the clicked tab (this is stored in the "DataValueField"), then it displays the context menu and cancels the default context menu action from the operating system. Then, when you click on one of the context menus - either "New" or "Edit" in my case - the JavaScript "onContextMenuItemSelected" is called. I now get the value parameter from the context menu, then I get a handler to the "parent" RadAjaxManager". I am then ready to make the Ajax request as shown in the last line of code below. //Get context menu item ("NEW", "EDIT" or whatever the Value parameter is). var contextMenuItem = e.get_item().get_value(); var ajaxManager = $find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>"); //Must always follow this standard when making ajax calls - "[name of caller]*..." ajaxManager.ajaxRequest("MenuTab" + "*" + tabValue + "*" + contextMenuItem); There is a trick here, and that is to include the "name of the caller" in all Ajax request. Since we use a proxy manager, all Ajax calls will expose everything from the "parent" Ajax manager. This will only be a problem if you have several different "OnAjaxRequest" on the same page. In my case, I have an Ajax request in a content page that uses this user control ("myUserControl.ascx"). The RadAjaxManager is defined in the master page, and the content page in question therefore has a RadAjaxManagerProxy definition as does the user control. Thus, the page that is executed will then have a RadAjaxManager from the master page and one proxy from the content page and one proxy from the user control. In a scenario like this, RadAjaxManager will call both "OnAjaxRequest" functions. In my case, the "RadAjaxmanagerMenuEdit_AjaxRequest" in "myUserControl.ascx.cs" will be called, and a routine called "RadAjaxManagerArticle_AjaxRequest" in the content page (containg the myUserControl.ascx) will also be called. We, of course, need a way to distinguish between the two calls, and I have done this through the arguments I set in the JavaScript code. Note the comment in the code above "//Must always follow this standard when making ajax calls - "[name of caller]*...". I therefore always put the name of the caller - in the case above it is "MenuTab" - as the first parameter in the argument that I pass to "RadAjaxManagerMenuEdit_AjaxRequest" or "RadAjaxManagerArticle_AjaxRequest" (in the case of this latter, the name of the caller will be "Article*..."). I then use the "Split" function to get the various arguments I wish to pass into the ajax routine - see code below: From my user control code behind "myUserControl.ascx.cs": protected void RadAjaxManagerMenuEdit_AjaxRequest(object sender, Telerik.Web.UI.AjaxRequestEventArgs e) { string strArg = e.Argument; string caller = (strArg.Split('*'))[0]; //First argument is always name of caller, i.e., "MenuTab*67*EDIT" if (caller == "MenuTab") { //Will get in strArg the following "MenuTab*[menu_id]*[name of context function]. F.ex. "MenuTab*67*EDIT". string menuId = (strArg.Split('*'))[1]; string contextMenuCommand = (strArg.Split('*'))[2]; string menuUrl = "~/MenuManager.aspx?menuid="; Response.Redirect(menuUrl + menuId + "&cmd=" + contextMenuCommand); } } The code here is now only executed when the caller is "MenuTab", thus avoiding that the code also executes when making Ajax calls from "Article" - and we achieve what was the intention. Good luck - Ajax is great, but sometimes a few tricks can make life a bit easier :) André Vold
Here's a short little BLOGGER BIO to tell you a little bit about my background - and why I chose to get into programming and SEO.
I grew up in Norway, but went to school in the U.S. I have a degreen in computer science from Arizona State University. After graduating I moved back to Norway where I got a job working at Norwegian Data and later IBM. I went on to do a Masters of Management at BI in Oslo. After several years as a senior executive at IBM I decided to start my own company, Apropos Internet. In 2004 I started Virosafe Norway, a company that imports and distributes data security products, and now I am CEO of Lumino as well.
It's always been essential for me to stay up to date on the latest trends and developments in technology - not only to stay current as a programmer, but also to ensure my success as an entrpreneur. Lumino blog articles contain a variety of topics that have been useful for my own businesses - perhaps you will find them useful as well.