When using RadTabStrip and RadMultiPage what should the callbacks look like.

0 Answers 30 Views
TabStrip
Thomas
Top achievements
Rank 1
Iron
Iron
Iron
Thomas asked on 12 Dec 2023, 05:01 PM

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?
}
Attila Antal
Telerik team
commented on 15 Dec 2023, 09:42 AM

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.

Thomas
Top achievements
Rank 1
Iron
Iron
Iron
commented on 15 Dec 2023, 01:21 PM

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.

Attila Antal
Telerik team
commented on 15 Dec 2023, 02:12 PM

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>

Thomas
Top achievements
Rank 1
Iron
Iron
Iron
commented on 15 Dec 2023, 02:54 PM | edited

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]

 

Attila Antal
Telerik team
commented on 15 Dec 2023, 03:25 PM | edited

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;
    }
}
Thomas
Top achievements
Rank 1
Iron
Iron
Iron
commented on 15 Dec 2023, 03:41 PM

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: 

  1. The user types info into a text field
  2. The user clicks a button
  3. The program reads data from a database based on what's in the text field
  4. The program adds tabs based on the data retrieved
Attila Antal
Telerik team
commented on 15 Dec 2023, 04:09 PM

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
Top achievements
Rank 1
Iron
Iron
Iron
commented on 15 Dec 2023, 04:13 PM

Attila, if dynamic controls should only be added in the PreInit or Init events, then how can the GUI be updated based on user actions?
Attila Antal
Telerik team
commented on 18 Dec 2023, 10:42 AM

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.

Thomas
Top achievements
Rank 1
Iron
Iron
Iron
commented on 18 Dec 2023, 02:08 PM

Attila, thank you for the reply.

So if I want this behavior:

  1. User types something into a textfield
  2. User clicks a SEARCH button
  3. The web app queries a database
  4. RadTabs and RadPages are added dynamically based upon what was found in the database.
  5. TabClick event handler is implemented to allow the web app to know when a tab change occurs.

It seems that step 5 isn't possible,

Attila Antal
Telerik team
commented on 18 Dec 2023, 02:23 PM

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
    }
}

Thomas
Top achievements
Rank 1
Iron
Iron
Iron
commented on 18 Dec 2023, 03:31 PM

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?

Attila Antal
Telerik team
commented on 19 Dec 2023, 12:23 PM

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>

Thomas
Top achievements
Rank 1
Iron
Iron
Iron
commented on 20 Dec 2023, 01:20 PM

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.

Attila Antal
Telerik team
commented on 20 Dec 2023, 03:34 PM

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.

No answers yet. Maybe you can help?

Tags
TabStrip
Asked by
Thomas
Top achievements
Rank 1
Iron
Iron
Iron
Share this question
or