I have implemented a web application that uses the RadTabStrip and RadMultiPage. The tabs and pages are dynamically created when the page is loaded. I did not create a TabStrip_TabClick() callback and when I click on a tab, the tab's associated page shows up as expected - everything works fine!
Now I want to intercept the TabClick() callback in order to do some additional processing before the page is redisplayed.
When I add the TabClick() callback, clicking on a tab does not trigger the page to be displayed.
What basic code needs to be in the callback in order to trigger the default page load behavior?
protected void myTabStrip_TabClick(object sender, RadTabStripEventArgs e)
{
// What
// goes
// here?
}
Hi Thomas,
It sounds like there is no PostBack initiated. If that is the case, the TabStrip might be missing the AutoPostBack="true" feature.
On a side note, if you are creating the controls dynamically, use the PreInit or Init events of the Page. You can check out the official documentation at Microsoft Learning here: ASP.NET Page Life-Cycle Events. This is not related to the issue, but it's a common mistake by many developers and could potentially cause issues in the future.
Attila, thank you for your reply.
If I omit the TabClick routine, then the AutoPostBack is not needed. When I add the empty TabClick routine,then it doesn't matter if the AutoPostBack is true or false, the behavior is the same: Clicking on the tab does not activate the associated MultiPage.
Did you associate the MultiPageView with the TabStrip?
<telerik:RadTabStrip runat="server" ID="RadTabStrip1" MultiPageID="RadMultiPage1"> </telerik:RadTabStrip> <telerik:RadMultiPage runat="server" ID="RadMultiPage1" SelectedIndex="0"> </telerik:RadMultiPage>
Attila, Yes, the RadMultiPage is associated with the RadTabStrip.
I have attached example code that will demonstrate the issue. As the code is now it will work fine: there is no TabClick handler but clicking on the tab swaps pages without issue. If I add OnTabClick="mainTabStrip_TabClick" AutoPostBack="true" then the tab click stops working.
[Attachment removed by Admin]
Hi Thomas,
Thanks for sharing the sample. I've removed the attachment because it contains the licensed assemblies. Please do not share those publicly in the forums.
By looking at the source code I see that the problem is with the way the Tabs are created.
With the following approach, the Tabs are created initially but not PostBacks. So when you enable the AutoPostBack of the Control, the Tabs are no longer created.
protected void Page_Load(object sender, System.EventArgs e) { if (!Page.IsPostBack) { AddTab("Test Tab 1", "~/middleearth.jpg"); AddTab("Test Tab 2", "~/NarniaMap.jpg"); mainTabStrip.Tabs[0].Selected = true; multiPage.PageViews[0].Selected = true; } }
To fix the issue
Generally speaking, when creating Controls dynamically, always use the PreInit or Init events and also always create the controls (without the "IsPostBack" condition). The Load event is used to set/change properties. There you will need the condition "!IsPostBack" because you do not want to reset the user-selected option to the same as it was at the initial load.
For more details, you can check out the ASP.NET Page Life-Cycle Events
Example
protected void Page_PreInit(object sender, System.EventArgs e) { AddTab("Test Tab 1", "~/middleearth.jpg"); AddTab("Test Tab 2", "~/NarniaMap.jpg"); } protected void Page_Load(object sender, System.EventArgs e) { if (!IsPostBack) { mainTabStrip.Tabs[0].Selected = true; multiPage.PageViews[0].Selected = true; } }
Attila, thank you for the speedy feedback.
I put the AddTab() calls into the Page_Load() for simplicity in the example, but my actual web app adds the tabs in a button click callback:
Creating controls dynamically should only be done in the PreInit or Init events as mentioned in the official documentation: ASP.NET Page Life-Cycle Events. If there are issues, this would be the solution.
Thomas,
For instance, you can create the controls and make them hidden initially. On a button click you can make them visible.
The point is, if you create ASP.NET Server Controls, their ViewState will only be tracked if doing that before the Page Load. If you look at the article I shared, you can see that the Control Events (e.g. Button click) trigger after the Page Load which is too late for creating Controls. The ViewState tracking kicks in in the Page Load.
If you're working with generic HTML elements, then you can create them at any point you wish. Those do not utilize the ViewState and it would not matter when they are created.
I hope this will help clarify the problem.
Attila, thank you for the reply.
So if I want this behavior:
It seems that step 5 isn't possible,
You can do that too. Thanks to the ViewState and WebForms, every form control value is submitted when a PostBack occurs.
That means, you can access the Request.Form[] data by the Control's UniqueID even as early as PreInit or Init.
Example
protected void Page_PreInit(object sender, EventArgs e) { if (Request.Form[TextBox1.UniqueID] != null) { string searchText = Request.Form[TextBox1.UniqueID].ToString(); // filter the database by the searchText // create the Tabs based on the results } } protected void Page_Init(object sender, EventArgs e) { if (Request.Form[TextBox1.UniqueID] != null) { string searchText = Request.Form[TextBox1.UniqueID].ToString(); // filter the database by the searchText // create the Tabs based on the results } }
Attila, thanks again for your quick feedback.
I redesigned my code so the Search Button event handler is empty and all the calls to query the database and populate the screen have been moved into the PreInit event handler. However, when I test TextBox1 is always NULL in the PreInit event handler so the page errors. Does TextBox1 need a special property setting for this to work?
This is the complete code I used for testing. The TextBox is always found.
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <telerik:RadButton runat="server" ID="RadButton1" Text="Postback" AutoPostBack="true" /> <script runat="server"> protected void Page_PreInit(object sender, EventArgs e) { if (Request.Form[TextBox1.UniqueID] != null) { string searchText = Request.Form[TextBox1.UniqueID].ToString(); // filter the database by the searchText // create the Tabs based on the results } } protected void Page_Init(object sender, EventArgs e) { if (Request.Form[TextBox1.UniqueID] != null) { string searchText = Request.Form[TextBox1.UniqueID].ToString(); // filter the database by the searchText // create the Tabs based on the results } } </script>
Thank you again for the reply.
My code matches your code except I use an asp::Button and your code is embedded in a <script> and my code is "code behind" in a CS file.
I only embedded it in the Script, so I can share a compact snippet that you can copy/paste in one place, however, this works even if I move the Backend code to the CodeBehind file.
If this does not work for you, there might be some other issues.