Updatepanel in ascx refreshing the whole control - asp.net

I've got a sitecore proejct, in which I have prepared a sub-layout in the form of an ascx User Control. I need to set up cascading drop downs in this user control, and based on what I found an UpdatePanel is the way to go. The problem is that the UpdatePanel seems to be refreshing the whole control, which I don't think is the correct behaviour.
I understand there are some similar questions on SO, but none of the solutions worked for me. I'm also beginning to suspect that this may be a Sitecore specific issue.
Here is a code sample of the user control:
<p><%= MyItem.Text %>" /></p>
<asp:UpdatePanel ID="LocationFilterUpdatePanel" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DDL1" OnSelectedIndexChanged="DDL1_SelectedIndexChanged" runat="server" AutoPostBack="true">
</asp:DropDownList>
<asp:DropDownList ID="DDL2" OnSelectedIndexChanged="DDL2_SelectedIndexChanged" runat="server" AutoPostBack="true">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
And the Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
var context = new SitecoreContext();
//Get Model from Sitecore
DDL1.DataSource = Model.Data;
DDL1.DataValueField = "Id";
DDL1.DataTextField = "Name";
DDL1.DataBind();
}
}
protected void DDL1_SelectedIndexChanged(object sender, EventArgs e)
{
var context = new SitecoreContext();
//Get Model from Sitecore
DDL2.DataSource = Model.Data;
DDL2.DataValueField = "Id";
DDL2.DataTextField = "Name";
DDL2.DataBind();
}
protected void DDL2_SelectedIndexChanged(object sender, EventArgs e)
{
}
The page loads fine, but (when debugging) changing the DDL1's index it will show a Null exception in MyItem.Text. This is outside the control panel. Note: I have also added a script manager.
There are plenty of things I've tried. Setting different update modes, updated the AjaxToolkit in my solution by executing Install-Package AjaxControlToolkit from the Package Manager Console... but the behaviour remains the same.
Thank you.

Put the databinding for DDL1 to the OnInit, rather than the Page_Load.
And don't include the if statement in there, just do the databind.
After the OnInit the selected values will be correctly set and you will be able to access the DDL1's options in the other event handlers.

You have asp:DropDownList control with an AutoPostBack set to true.
Remove the AutoPostBack=true from the Dropdownlist control and set an Async trigger for your UpdatePanel, set to the Dropdownlist and its eventname="SelectedIndexChanged"
This is a know issue, and you find a lot of documentation about it.

Related

UpdatePanel with TextBox.OnTextChanged Async Event not firing

I have a textbox for inputting a desired username. When the user types in their name and the input loses focus, I want to send an async postback to check whether their username is already taken. This works fine in the cases that no error is thrown, but I want to handle errors, as well.
Per MSDN, I've added an AsyncPostBackError handler to the ScriptManager. I've tried this both on every page load and only on non-postback page loads.
I have my TextBox in an UpdatePanel like so:
<asp:UpdatePanel ID="upLogin" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="tbLogin" runat="server" placeholder="username"
OnTextChanged="tbLogin_TextChanged" required />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tbLogin" EventName="TextChanged" />
</Triggers>
</asp:UpdatePanel>
In the code-behind, I have:
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.GetCurrent(Page).AsyncPostBackError +=
BootstrapLogin_AsyncPostBackError;
}
void BootstrapLogin_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
tbLogin.Attributes.Remove("data-success");
tbLogin.Attributes["data-error-message"] = myErrorMessage;
}
protected void tbLogin_TextChanged(object sender, EventArgs e)
{
throw new Exception("what?");
}
I also added Async="true" to my Default.aspx Page markup.
When I have AutoPostBack="true" on my TextBox, the error is thrown and the AsyncPostBackError handler is never called. For some reason, during the postback, Page.IsAsync is false. I suspect this is the reason (or indication of why) it's not being handled.
When I set AutoPostBack="false", no postback is fired at all, despite the specified trigger.
Ideas?
It looks like following code doesn't work as intended
ScriptManager.GetCurrent(Page).AsyncPostBackError +=
BootstrapLogin_AsyncPostBackError;
Instead of that I just set the OnAsyncPostBackError property of the ScriptManager in markup and it worked with AutoPostback = "True" in your TextBox.
<asp:ScriptManager ID="ScriptManager1" runat="server" OnAsyncPostBackError="BootstrapLogin_AsyncPostBackError"></asp:ScriptManager>
Not sure why your code didn't work. It picks up the correct ScriptManager.
UPDATE
Solved it!
I should refresh my knowledge on Page lifecycle :(
Actually, we should add your code into Page_Init rather than in Page_Load. Following works perfectly.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ScriptManager.GetCurrent(Page).AsyncPostBackError +=
BootstrapLogin_AsyncPostBackError;
}
UPDATE 2
See this screen capture
Hope this helped!

Literal Control text rendering doesn't work in Update Panel

In my ASP.NET app I have Update Panel and Custom server control in it.
This Custom control has inside Literal Control. I try to set it's text property programmatically. But it doesn't render, because Literal Control is in Update Panel.
How can I solve this? Thanks very much.
Here is my code:
<asp:UpdatePanel runat="server" ID="updPanel">
<ContentTemplate>
<st:AspGridViewTitlePanel runat="server" ID="GridTitle" Width="100%">
</st:AspGridViewTitlePanel>
</ContentTemplate>
</asp:UpdatePanel>
AspGridViewTitlePanel - it's my server control. It has such code:
this.myLiteralControl = new LiteralControl();
this.myLiteralControl.Text = "Some text";
protected void page_load(object sender, args e) {
if (!Page.IsPostBack) {
LiteralControl myLiteralControl = new LiteralControl();
myLiteralControl.Text = #"<span> MY TEXT </span>";
UP1.ContentTemplate.Controls.Add(myLiteralControl);
}
}
Adding controls dynamically to an UpdatePanel in ASP.NET AJAX

Controls within .ascx are not displaying their new value on postback

This seems like an elementary issue but it has me stumped.
I have a main page which loads a custom control (.ascx) on page_load.
This custom control has two fields. One of them being a dropdownlist and the other being a text box. When the dropdownlist changes value it triggers a post back, some logic is executed server side and a value is generated for the textbox. I stepped through the code and the value is created and assigned correctly. However, when the page is rendered the value does not change.
If I change the textbox value to "QQQ" and trigger the postback, "QQQ" stays in the textbox so I can verify viewstate is working.
Is there any reason why the generated value is not being displayed in the form on postback. This process works fine on the initial page load.
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string ascxPath = #"~/_CONTROLTEMPLATES/TRC_BITS.ascx";
TRC_BITS control = Page.LoadControl(ascxPath) as TRC_BITS;
phForm.Controls.Add(control);
}
.ascx
<asp:TextBox ID="message" runat="server" TextMode="MultiLine" /><br/>
<asp:DropDownList ID="year" runat="server" AutoPostBack="true">
<asp:ListItem Text="2011">2011</asp:ListItem>
<asp:ListItem Text="2012">2012</asp:ListItem>
<asp:ListItem Text="2013">2013</asp:ListItem>
</asp:DropDownList>
.ascx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
year.SelectedValue = DateTime.Now.Year.ToString();
}
if (year.SelectedValue == 2012)
message.Text = "ABC";
else
message.Text = "XYZ";
}
Because you're adding these controls to the page dynamically, you need to assign an ID to the user control. Make sure to assign the same ID to the controls every time the page is posted back, and the fields will be repopulated from ViewState.
Also, as Shai suggested, it would be more appropriate if you loaded the controls during OnInit instead of Page_Load. The situation is a little different with user controls, but in general you want to add your dynamic content before the LoadViewState method is executed.
If you're looking for something to take the pain out of persisting dynamic content, I would suggest taking a look at the DynamicControlsPlaceHolder.
Because you are adding the controls dynamically, you need to add them during the page's oninit event.
Try it, believe me. Go for it. Yalla.

Can I put a Timer in Ajax updatePannel in a masterpage?

I made a very simple pannel updating wich will query a database and show a message on masterpage through a label.
Thus, I've put an updatePannel with a label and a timer within (obviously with a scriptManager) in my site's masterpage.
However, when I try to interact with the timer1 object, I receive an error message: "object not set to an instance of an object". I not receive this message when placing the schema in a blank page (without masterpage).
I must to run the query in masterpage because the users need to receive information whatever they are in my site.
How can I correctly place the components to do this work? what I'm doing wrong?
Thanks!
I just tried it within a master page without a problem. Here is the relevant code:
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" />
<asp:UpdatePanel ID="updMessage" runat="server">
<ContentTemplate>
<asp:Label ID="lblMessage" runat="server" />
<asp:Timer ID="tmrMessage" Interval="5000" ontick="tmrMessage_Tick" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
From master page code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["Message"] = 1;
}
}
protected void tmrMessage_Tick(object sender, EventArgs e)
{
int message = (int)Session["Message"];
lblMessage.Text = message.ToString();
Session["Message"] = ++message;
}
The problem was where I was putting the panel, label and timer. I put in contentPlaceHolder, where the problem occours. Now I put the control in the form tag, then the problem is solved.

Dropdown list selected index changed

I did my drop down list that get its values from the database and when running the application, it did not work and the compiler did not see the code.
// aspx
<asp:UpdatePanel ID="UpdatePanel3" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DDlProductFamily" runat="server"
ondatabound="DDlProductFamily_DataBound"
onselectedindexchanged="DDlProductFamily_SelectedIndexChanged">
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DDlProductFamily" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
// cs
protected void DDlProductFamily_SelectedIndexChanged(object sender, EventArgs e)
{
using (SqlConnection Con = Connection.GetConnection())
{
SqlCommand Com = new SqlCommand("SelectThumbByProductFamily", Con);
Com.CommandType = CommandType.StoredProcedure;
Com.Parameters.Add(Parameter.NewInt("#ProductCategory_Id",
DDlProductFamily.SelectedValue.ToString()));
SqlDataAdapter DA = new SqlDataAdapter(Com);
DA.Fill(dt);
DataList1.DataSource = dt;
DataList1.DataBind();
}
}
Check if listbox has property AutoPostBack="True".
You need to be loading the DLL data on, for example, Page Load, it is empty so your DDL will never have its SelectedIndex changed.
You need to do something like this psuedo code:
Page_load
{
if(!IsPostBack)
{
BindData();
}
}
BindData()
{
// Do your DataBase/whatever call to fill the DDL
}
And your code for protected void DDlProductFamily_SelectedIndexChanged(object sender, EventArgs e) stays the same.
Your DDL will also need the property AutoPostBack="true"
Do you have AutoEventWireup="true" set in the page directive at the top of your ASPX page? You will need this setting set to true in order for your code to work.
For more information please see Information about the AutoEventWireup attribute:
In Visual Studio .NET or in Visual
Studio 2005, events are bound to
event-handler methods using event
delegates. If you use the Web Forms
Designer to design Web Forms, the
designer automatically generates code
to bind events to their event-handler
methods.

Resources