This is a migrated thread and some comments may be shown as answers.

RadAjaxPanel, Viewstate, and Dynamic Controls

7 Answers 363 Views
Ajax
This is a migrated thread and some comments may be shown as answers.
Michael Landy
Top achievements
Rank 1
Michael Landy asked on 18 Mar 2010, 11:53 PM
I have a function that adds dynamic controls to an RadAjaxPanel.  The dynamic controls are RadComboBox and some others.  Everything is working as expected.  On page postbacks, the values for these controls are properly set.

Outside of the panel is a button.  If the user selects this button, the contents of the RadAjaxPanel are modified.  The update panel looks great at the end of this postback, as it has the new control and data.  The problem happens on a subsequent postback.  During the next postback the update panel is recreated with the correct controls however the data/viewstate for the controls is gone.  I can only assume that the controls that were added during a postback client event to the update panel did not save the viewstate. 

The subsequent postback does not contain the state for the control that was added.  My sample code is below.  Here is how to see the problem:

1. The page displays with two comboboxes.
2.  Select an item in the first combobox and the second one repopulates.  This is working as expected.
3.  Press the button on the page and the update panel is created with a single combobox and a new set of values.  This is working as expected.
4.  Press the button again, as this time it just implements a standard postback with no changes.  THe combobox no longer has its values.

Since the viewstate of the objects happens after the PreRender event, there is no reason why the state should not be saved.  What is happening?

<%@ Page Title="" Language="C#" AutoEventWireup="true" CodeFile="Trials.aspx.cs" Inherits="Reporteratti.Trials" %> 
<html> 
<head runat="server">  
          
    </head> 
<body> 
    <form id="form1" runat="server">  
<asp:ScriptManager runat="server" ID="ScriptManager1">  
   <Scripts> 
       <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" /> 
       <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" /> 
       <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" /> 
   </Scripts></asp:ScriptManager> 
This page is for trying stuff  
    <telerik:RadAjaxPanel ID="updatePanel" runat="server"   
        HorizontalAlign="NotSet"  > 
    </telerik:RadAjaxPanel> 
    <asp:Button ID="Button2" runat="server"   
        Text="Cause a Postback changing the update panel contents" onclick="Button2_Click" />   
    </form> 
</body> 
</html> 
 

namespace Reporteratti  
{  
 
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Web;  
    using System.Web.UI;  
    using System.Web.UI.WebControls;  
    using Telerik.Web.UI;  
    using System.Collections.Specialized;  
 
    public partial class Trials : System.Web.UI.Page  
    {  
        protected void Page_Load(object sender, EventArgs e)  
        {  
            RadComboBox cmb1;  
            RadComboBox cmb2;  
            RadComboBox cmbX;  
            // Rebuild the dynamic controls based on which should be shown  
            if (Session["page"] == null)  
            {  
                cmb1 = new RadComboBox();  
                cmb1.ID = "first";  
                updatePanel.Controls.Add(cmb1);  
                cmb1.AutoPostBack = true;  
                cmb1.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(cmb1_SelectedIndexChanged);  
 
                cmb2 = new RadComboBox();  
                cmb2.ID = "second";  
                cmb2.AutoPostBack = true;  
                cmb2.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(cmb1_SelectedIndexChanged);  
 
                updatePanel.Controls.Add(cmb2);  
 
                if (!this.IsPostBack)  
                {  
                    cmb1.Items.Add(new RadComboBoxItem("Item A", "1"));  
                    cmb1.Items.Add(new RadComboBoxItem("Item B", "2"));  
                    cmb1.Items.Add(new RadComboBoxItem("Item C", "3"));  
 
                    cmb2.Items.Add(new RadComboBoxItem("Item M", "1"));  
                    cmb2.Items.Add(new RadComboBoxItem("Item N", "2"));  
                    cmb2.Items.Add(new RadComboBoxItem("Item O", "3"));  
                }  
 
            }  
            else  
            {  
                cmbX = new RadComboBox();  
                cmbX.ID = "NewPage";  
                updatePanel.Controls.Add(cmbX);  
 
                // This combobox is only filled in the selected event  
            }  
 
        }  
 
        void cmb1_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)  
        {  
            string sSelect = e.Text;  
            string sValue = e.Value;  
 
            RadComboBox dd = (RadComboBox)o;  
 
            if (dd.ID == "first")  
            {  
                RadComboBox cmb2 = updatePanel.FindControl("second") as RadComboBox;  
 
                if (cmb2 != null)  
                {  
                    cmb2.Items.Clear();  
                    cmb2.Items.Add(new RadComboBoxItem("Item P", "5"));  
                    cmb2.Items.Add(new RadComboBoxItem("Item Q", "6"));  
                    cmb2.Items.Add(new RadComboBoxItem("Item R", "7"));  
                }  
            }  
 
 
        }  
        protected void Button2_Click(object sender, EventArgs e)  
        {  
            // If the second page is not showing, show it.  
            // If the page is already showing, do nothing and act like a single postback  
 
            if (Session["page"] == null)  
            {  
                // Clear the update panel  
                // Create the single combobox  
                // Fill the combobox  
                updatePanel.Controls.Clear();  
 
                RadComboBox cmbX = new RadComboBox();  
                cmbX.ID = "NewPage";  
                updatePanel.Controls.Add(cmbX);  
 
                cmbX.Items.Clear();  
                cmbX.Items.Add(new RadComboBoxItem("Item XXX", "14"));  
                cmbX.Items.Add(new RadComboBoxItem("Item YYY", "32"));  
                cmbX.Items.Add(new RadComboBoxItem("Item ZZZ", "23"));  
                Button2.Text = "Cause a postback";  
                Session["page"] = 2;  
            }  
 
 
        }  
}  
}  
 


7 Answers, 1 is accepted

Sort by
0
Michael Landy
Top achievements
Rank 1
answered on 19 Mar 2010, 04:03 PM
If I substitute a regular DropDownList for the RadComboBox, the problem persists.  This means it is not native to the RadComboBox control.

If I substitute the asp:UpdatePanel for the Telerik RadAjaxPanel, the code above works as expected and the viewstate is happy.  This means that  the RadAjaxPanel has some issues with this scenario.  I would hate to use the asp:UpdatePanel since I paid for Telerik.  By the way, there is some modifications to the code above since asp:UpdatePanel uses ContentTemplateContainer to add new controls whereas the RadAjaxPanel directly accesses the Control collection.

So, I believe you have a bug in the RadAjaxPanel.
0
Iana Tsolova
Telerik team
answered on 24 Mar 2010, 01:22 PM
Hello Michael,

I tested the provided page with no ajax at all and was able to replicate the issue you experience with RadAjax. Please note that you need to make sure your page works as expected without ajax and then ajaxify it as described here.
However I suggest that you (re)create on Page_Load either the ComboBox and its item.

All the best,
Iana
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.
0
Michael Landy
Top achievements
Rank 1
answered on 25 Mar 2010, 03:15 PM
I believe you are still incorrect.  If I implement regular postbacks, NO AJAX, it works correctly.  The viewstate and the new object are created correctly.  I replaced the update panel with a place holder.  The new object creation in the event works correctly and viewstate is stored.  If I use Microsoft's update panel, it works correctly and the viewstate is restored.  If I user the RadAjaxPanel, the viewstate is NOT correctly stored.

So, I believe you are in error.  The RadAjaxPanel is not behaving like the UpdatePanel from Microsoft.  The example code below shows that it works without being Ajaxified.  Therefore, i can only conclude that the RadAjaxPanel is NOT a replacement for the UpdatePanel.  Can you please confirm this or show me that it works?

Here is the non ajaxified version:  (If you want, I can post the MS update panel code as well showing it works)
namespace Reporteratti  
{  
 
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Web;  
    using System.Web.UI;  
    using System.Web.UI.WebControls;  
    using Telerik.Web.UI;  
    using System.Collections.Specialized;  
 
    public partial class Trials : System.Web.UI.Page  
    {  
        protected void Page_Load(object sender, EventArgs e)  
        {  
            DropDownList cmb1;  
            DropDownList cmb2;  
            DropDownList cmbX;  
 
            // Rebuild the dynamic controls based on which should be shown  
 
            if (Session["page"] == null)  
            {  
                cmb1 = new DropDownList();  
                cmb1.ID = "first";  
                PlaceHolder1.Controls.Add(cmb1);  
//                updatePanel.Controls.Add(cmb1);  
                cmb1.AutoPostBack = true;  
                //cmb1.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(cmb1_SelectedIndexChanged);  
                cmb1.SelectedIndexChanged += new EventHandler(cmb1_SelectedIndexChanged);  
                cmb2 = new DropDownList();  
                cmb2.ID = "second";  
                cmb2.AutoPostBack = true;  
 
                PlaceHolder1.Controls.Add(cmb2);  
 
                if (!this.IsPostBack)  
                {  
                    cmb1.Items.Add(new ListItem("Item A", "1"));  
                    cmb1.Items.Add(new ListItem("Item B", "2"));  
                    cmb1.Items.Add(new ListItem("Item C", "3"));  
 
                    cmb2.Items.Add(new ListItem("Item M", "1"));  
                    cmb2.Items.Add(new ListItem("Item N", "2"));  
                    cmb2.Items.Add(new ListItem("Item O", "3"));  
                }  
 
            }  
            else  
            {  
                cmbX = new DropDownList();  
                cmbX.ID = "NewPage";  
                PlaceHolder1.Controls.Add(cmbX);  
 
                // This combobox is only filled in the selected event  
            }  
 
        }  
 
        void cmb1_SelectedIndexChanged(object sender, EventArgs e)  
        {  
            DropDownList dd = (DropDownList)sender;  
 
            if (dd.ID == "first")  
            {  
                DropDownList cmb2 = PlaceHolder1.FindControl("second") as DropDownList;  
 
                if (cmb2 != null)  
                {  
                    cmb2.Items.Clear();  
                    cmb2.Items.Add(new ListItem("Item P", "5"));  
                    cmb2.Items.Add(new ListItem("Item Q", "6"));  
                    cmb2.Items.Add(new ListItem("Item R", "7"));  
                }  
            }  
 
        }  
 
        void cmb1_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)  
        {  
            string sSelect = e.Text;  
            string sValue = e.Value;  
 
            RadComboBox dd = (RadComboBox)o;  
 
            if (dd.ID == "first")  
            {  
                RadComboBox cmb2 = PlaceHolder1.FindControl("second") as RadComboBox;  
 
                if (cmb2 != null)  
                {  
                    cmb2.Items.Clear();  
                    cmb2.Items.Add(new RadComboBoxItem("Item P", "5"));  
                    cmb2.Items.Add(new RadComboBoxItem("Item Q", "6"));  
                    cmb2.Items.Add(new RadComboBoxItem("Item R", "7"));  
                }  
            }  
 
 
        }  
 
        protected void Button2_Click(object sender, EventArgs e)  
        {  
            // If the second page is not showing, show it.  
            // If the page is already showing, do nothing and act like a single postback  
 
            if (Session["page"] == null)  
            {  
                // Clear the update panel  
                // Create the single combobox  
                // Fill the combobox  
                PlaceHolder1.Controls.Clear();  
 
                DropDownList cmbX = new DropDownList();  
                cmbX.ID = "NewPage";  
                PlaceHolder1.Controls.Add(cmbX);  
 
                cmbX.Items.Clear();  
                cmbX.Items.Add(new ListItem("Item XXX", "14"));  
                cmbX.Items.Add(new ListItem("Item YYY", "32"));  
                cmbX.Items.Add(new ListItem("Item ZZZ", "23"));  
                Button2.Text = "Cause a postback";  
                Session["page"] = 2;  
            }  
 
 
        }  
}  
}  
 
 

I removed the Telerik RadAjaxPanel and put in a place holder control so I could update the page tree like the original example.
0
Iana Tsolova
Telerik team
answered on 31 Mar 2010, 08:30 AM
Hi Michael,

I tested the page with the DropDownList controls and I observed that it behaves the same way with RadAjax and without RadAjax. As the previously provided page with the RadComboBoxes, which works the same way with or without ajax.
So before using RadAjax you should make sure you page works as desired with regular postbacks and then you can ajaxify it.

Kind regards,
Iana
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.
0
Michael Landy
Top achievements
Rank 1
answered on 31 Mar 2010, 01:37 PM
I think you are missing the bug.  Please follow these steps and you will see that the code I posted (both Ajax and non-Ajax) behave differently.

When you run the code, there is a button named "Cause a Postback changing the update panel contents".  Press this button and you will see a page with a single filled in combobox.  The button's name is now "Cause a postback".  If you press "Cause a postback" you will see that the combobox is no longer filled (Ajax Version) but it is filled in in the (non-Ajax) version.  How can you tell me that this is the same behavior?

If this is not happening on your version, please send me the code you are using.

Thank you
0
Iana Tsolova
Telerik team
answered on 01 Apr 2010, 12:50 PM
Hi Michael,

I will try the code again and follow your steps in order to replicate the issue and will write you back in this thread later.

Regards,
Iana
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.
0
Iana Tsolova
Telerik team
answered on 08 Apr 2010, 12:10 PM
Hi Michael,

I followed the provided steps and prepared a sample project attached to this post. There you can find two pages - Ajax.aspx and NoAjax.aspx. Both behave the same way on my side, e.g. the dynamically added combo box items are lost after the second postback.

All the best,
Iana
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.
Tags
Ajax
Asked by
Michael Landy
Top achievements
Rank 1
Answers by
Michael Landy
Top achievements
Rank 1
Iana Tsolova
Telerik team
Share this question
or