Can I put a Timer in Ajax updatePannel in a masterpage? - asp.net

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.

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!

Updatepanel in ascx refreshing the whole control

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.

How do I load two ASP.NET UserControls on Demand?

I want load two user controls on demand.
asp:UpdatePanel ID="UpdatePanel1" runat="server"
ContentTemplate
asp:Button ID="Button1" runat="server" Text="Button" UseSubmitBehavior="false"
OnClick="Button1_Click" /
div id='Div_UserControlPlace' enableviewstate="true" runat="server"
/div
/ContentTemplate
Triggers
asp:PostBackTrigger ControlID="Button1" /
/Triggers
/asp:UpdatePanel
asp:UpdatePanel ID="UpdatePanel2" runat="server"
ContentTemplate
asp:Button ID="Button2" runat="server" Text="Button" UseSubmitBehavior="false"
OnClick="Button2_Click" /
div id='Div_UserControlPlace2' enableviewstate="true" runat="server"
/div
/ContentTemplate
aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Control FeaturedProductUserControl = new Control();
FeaturedProductUserControl = LoadControl("WebUserControl1.ascx");
FeaturedProductUserControl.EnableViewState = true;
Div_UserControlPlace.Controls.Add(FeaturedProductUserControl);
}
protected void Button2_Click(object sender, EventArgs e)
{
Control FeaturedProductUserControl2 = new Control();
FeaturedProductUserControl2 = LoadControl("WebUserControl2.ascx");
FeaturedProductUserControl2.EnableViewState = true;
Div_UserControlPlace2.Controls.Add(FeaturedProductUserControl2);
}
I load the first user control by clicking on the first button - this works properly but when I click on the other button to load the second UserControl, the first UserControl disappears and the second UserControl loads.
Thanks
IFA_User
You should use the Placeholder control to dynamically add your controls to the form.
Take a look at my last responses about dynamic controls:
OnClick event of dynamically created LinkButtons is not working
Dynamically Added DropDownlists Are Not Firing SelectedIndexChanged Event
Dynamically create an ImageButton
Now I already have some code working for demo purpose, each dynamic user controls keeps its state across post backs
This is the output:
ASPX
<asp:PlaceHolder runat="server" ID="addresses" /><br />
<asp:Button Text="Add Address" runat="server" ID="addAddress" OnClick="addAddress_Click" />
ASPX Code behind
protected void Page_PreLoad(object sender, EventArgs e)
{
for (int i = 0; i < this.DynamicControlsCount; i++)
{
var c = this.LoadControl("~/AddressControl.ascx");
this.addresses.Controls.Add(c);
}
}
protected void addAddress_Click(object sender, EventArgs e)
{
this.DynamicControlsCount++;
var c = this.LoadControl("~/AddressControl.ascx");
this.addresses.Controls.Add(c);
}
protected int DynamicControlsCount
{
get
{
if (this.ViewState["ac"] == null)
{
return 0;
}
return (int)this.ViewState["ac"];
}
set
{
this.ViewState["ac"] = value;
}
}
ASCX
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddressControl.ascx.cs" Inherits="WebApplication1.AddressControl" %>
<asp:Panel ID="Panel1" runat="server" GroupingText="Address" DefaultButton="btnSave">
Street: <asp:TextBox runat="server" ID="txtStreet" /><br />
City: <asp:TextBox runat="server" ID="txtCity" /><br />
<asp:Button Text="Save" runat="server" ID="btnSave" OnClick="btnSave_Click" />
</asp:Panel>
<asp:Panel runat="server" GroupingText="Address Summary" Visible="false" ID="summary">
<asp:Label ID="lblStreet" runat="server" /><br />
<asp:Label ID="lblCity" runat="server" />
</asp:Panel>
ASCX Code behind
protected void btnSave_Click(object sender, EventArgs e)
{
this.summary.Visible = true;
this.lblCity.Text = "Selected city: " + this.txtCity.Text;
this.lblStreet.Text = "Selected street: " + this.txtStreet.Text;
}
When a user control is created in the HTML, asp.net will persist across postbacks without any user interaction. But if you are loading them programatically (dynamically), they will not persist accross postbacks. So if you load them programmatically, you have the added task of persisting them programmatically as well. Use the ViewState (or Session I suppose) to store what has been loaded and perhaps any other necessary information that needs to be loaded between postbacks. Every single postback will require you to reload every control or else they will disappear.
There are couple of ways of doing it:
U can load the UserControls using Ajax. Benefit of using Ajax, is ur page does not get post back, thus for example, on click event of Button1, call a ajax(traditional/Jquery) to load UserControl1, and on button click of Button2 User control2.
Put the two button in two different updated panel, by doing this the click event will only refresh a part of ur page.
U have to save somewhere (ViewState/Session),which buttons are clicked, and upon clicking of any button check the value of that variable, and explicit load the control.
Points to note - If u want to get ur data back when ur page made a complete postback, then u have to add the controls keeping in mind the Page load event cycle.

Datalist placed inside a usercontrol

I have a usercontrol.Inside usercontrol I have a datalist and sqldatasource.Sqldatasource needs a parameter to databind the datalist.Usercontrol gets a parameter by this way,
private string _urunIDparam;
public string urunIDparam
{
get { return _urunIDparam; }
set {_urunIDparam = value; }
}
And then this parameter is added to the sqldatasource in onprerender of usercontrol by this way,
protected override void OnPreRender(EventArgs e)
{
SqlDataSourceHareketler.SelectParameters["urunID"].DefaultValue = urunIDparam;
DataListHareketAna.DataBind();
base.OnPreRender(e);
}
And the usercontrols parameter is given from a button that is placed aspx page like this,
protected void Button1_Click(object sender, EventArgs e)
{
MyUserControl1.urunIDPARAM = urunID;
}
And button and usercontrol is placed in an updatepanel inside an aspx page like this,
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<uc2:MyUserControl ID="MyUserControl1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click"/>
</ContentTemplate>
</asp:UpdatePanel>
And the problem when I hit a button inside datalist, my usercontrol disappears (datalist loses its items).
It sounds like you may need to do a postback check around your functions within the controls. I have seen this exact issue before, and I think this is what I had to do, but it has been awhile.
if (!IsPostback) {
//LoadData
}

UpdatePanel where Button Event does not fire

I have a UpdatePanel with a PlaceHold contained in it. I create some controls with Labels and Buttons, when Button is clicked it fires an Event that clears PlaceHolder and adds some Textboxes and a Button with an Event.
Problem is when this Button is click it appears to do a PostBack and does not fire Event associated with Button. I thought that since these controls are all contained within the UpdatePanel the would be no PostBack, am I missing the flow.
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<%--<%# Register assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.DynamicData" tagprefix="cc1" %>
--%>
<div id="content" > <!--start content div-->
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<br />
<asp:UpdatePanel ID="upBlog" runat="server" UpdateMode="Conditional">
<ContentTemplate >
<asp:PlaceHolder ID="phBlog" runat="server"></asp:PlaceHolder>
</ContentTemplate>
<Triggers >
<%-- <asp:AsyncPostBackTrigger EventName="Click" ControlID = "btnSave" />--%>
</Triggers>
</asp:UpdatePanel>
<br />
</div> <!--ends content div-->
</asp:Content>
//Code Behind
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
FirstView();
}
protected void Page_Load(object sender, EventArgs e)
{
}
private void FirstView()
{
FileStream fs = new FileStream(Server.MapPath(GlobalVar.compathver), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
DataSet dset = new DataSet();
dset.ReadXml(fs);
fs.Close();
//other controls
Button btnComments = new Button();
btnComments.ID = "mybtnComments" + i.ToString();
btnComments.BorderWidth = 0;
btnComments.Text = MyFunc.CountComments(row["ID"].ToString(), dset) + " Comments";
phBlog.Controls.Add(btnComments);
btnComments.CommandArgument = row["ID"].ToString();
btnComments.BorderWidth = 0;
btnComments.Command += new CommandEventHandler(Button1_Click)
}
private void CommentView(string ID) /// THIS DOES not FIRE
{
DataView myCommentView = GetCommentView(ID);
Button btnCommentSave = new Button();
btnCommentSave.ID = "mySavebtnComments" + i.ToString();
btnCommentSave.Text = "Publish";
btnCommentSave.BackColor = Color.Aquamarine;
phBlog.Controls.Add(btnCommentSave);
btnCommentSave.CommandArgument = row["ID"].ToString();
btnCommentSave.Click += new EventHandler(btnSave_Click);
}
protected void Button1_Click(object sender, CommandEventArgs e)
{
CommentView(e.CommandArgument.ToString());
}
protected void btnSave_Click(object sender, EventArgs e)
//protected void btnSave_Click(object sender, CommandEventArgs e)
{
FileStream fsxml = new FileStream(Server.MapPath(GlobalVar.compathver), FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
//other code
// XML Document Saved
xmldoc.Save(fsxml);
}
The UpdatePanel still does a postback. The whole page life-cycle is repeated when the button is clicked, and therefore the Page_Init and Page_Load for example will be executed again. AJAX does not remove the postbox, just hides it from the client.
I can't obviously see something wrong with the code you've posted however I would suggest you place a break point in the Page_Init as a start. This will be able to tell you if the postback is actually happening or not, since this will be fired if the button is indeed trying to fire the button click event. Keep in mind any click events is fired after the page life cycle completes (Theoretically).
On second look I would suggest that you change the Button event in the FirstView() method to a Click rather then a Command and see if this triggers the event.
it is better to add any event to the control before adding the control to another container.
secondly the button with the parameter name "btnCommentSave" will not work. You have to be careful on OnInit, OnLoad events. It is server-client side issue. The page pushed from server to client does not include the "btnCommentSave" button, so that this button stays at the clients page but it does not work.
btnComments works, because it is rendered by server before pushing to client at UpdatePanel's OnLoad function.
What rendered after OnLoad functions, does not work.

Resources