Yesterday I wrote simle example of updating UpdatePanel on timer.tick event. I noticed that on timer.tick event code of my form class is running from the beginning. Why? How to avoid it?
WebForm1.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="TestApp.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="False"
UpdateMode="Conditional" onload="UpdatePanel1_Load">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:Timer ID="Timer1" runat="server" Interval="5000" ontick="Timer1_Tick">
</asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
WebForm1.aspx.cs:
namespace TestApp
{
public partial class WebForm1 : System.Web.UI.Page
{
static Random rnd = new Random();
int b = rnd.Next(100); // always 1 value
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Timer1_Tick(object sender, EventArgs e)
{
UpdatePanel1.Update();
}
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
int a = rnd.Next(100); // changing value
Label1.Text = a.ToString() + " - changing value<br />" + b.ToString() + " - static value";
}
}
}
Why: Because the timer is enabled when the page loads. When the time you sit elapsed it will cause a postback to the server which will reload your page again, and this is why you see the debugger goes at the beginning of you form.
How to avoid it: Simply set Enabled property to false on page load, and then set it to true whenever you want the timer to start.
Documentation from MSDN "The Tick event is raised when the number of milliseconds specified in the Interval property has elapsed either since the Web page was rendered or since the previous Tick event."
Related
I find a code for setting countdown timer but it only shows minutes not seconds when page is load and also I want that when user click on button then countdown should start and also time (e.g 10:59) should be shown on the clicked button.
Following is the code:
aspx code (ASP.net C#)
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Reservation.aspx.cs" Inherits="Reservation" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManagerTimer" runat="server"></asp:ScriptManager>
<asp:Timer ID="timer1" runat="server" Interval="1000" OnTick="timer1_tick"></asp:Timer>
<asp:UpdatePanel id="updPnl"
runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="btnTimer" runat="server" BackColor="#05CC00" Height="35px" Text="Reserve" Width="89px" style="border-radius:8px" OnClick="btnTimer_Click"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timer1" EventName ="tick" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
aspx.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Reservation : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!ScriptManagerTimer.IsInAsyncPostBack)
Session["timeout"] = DateTime.Now.AddMinutes(10).ToString();
}
protected void timer1_tick(object sender, EventArgs e)
{
if (0 > DateTime.Compare(DateTime.Now,
DateTime.Parse(Session["timeout"].ToString())))
{
btnTimer.Text = ((Int32)DateTime.Parse(Session["timeout"].
ToString()).Subtract(DateTime.Now).Minutes).ToString();
}
}
}
if (0 > DateTime.Compare(DateTime.Now,
DateTime.Parse(Session["timeout"].ToString())))
{
btnTimer.Text = ((Int32)DateTime.Parse(Session["timeout"].
ToString()).Subtract(DateTime.Now).Minutes).ToString("HH:mm:ss");
}
TimeSpan.ToString() offers a variety of string formats. More info : MSDN
:)
During the page_load, I disable the timer. When I pressed Button1, I enable the timer, but the page refreshes. Therefore, it never reaches the timer_tick1. I need to show a popup after a certain amount of time a button is clicked. How do I prevent the refresh from happening?
Alerts Class
public static class Alert
{
public static void Show(string message, Page page)
{
// replaces the quotations to follow the script syntax
// quotations are interpretated as \\' in script code
string cleanMessage = message.Replace("'", "\\'");
string script = "<script type=\"text/javascript\">alert('" + cleanMessage + "');</script>";
// Gets the executing web page
Page tempPage = page;
// Checks if the handler is a Page and that the script isn't already on the page
if (tempPage != null & !tempPage.ClientScript.IsClientScriptBlockRegistered("alert"))
{
tempPage.ClientScript.RegisterClientScriptBlock(typeof(Alert), "alert", script); // this isn't working, but it works on a button click event.
}
}
}
Page Class
public partial class Test1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostback) {
Timer1.Enabled = false;
Label2.Text = "Panel refreshed at: " +
DateTime.Now.ToLongTimeString(); // Checks if page reloads
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{ // i added a breakpoint here. It doesn't even pass through.
Alert.Show("hehehehe", this); //PopUp Shows up.
Timer1.Enabled = false; //Cancels Timer
Label1.Text = "Panel refreshed at: " +
DateTime.Now.ToLongTimeString(); // Checks if update panel reloads
}
protected void Button1_Click1(object sender, EventArgs e)
{
Timer1.Enabled = true; //Starts Timer. It seems to refresh the page.
}
}
script
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Test1.aspx.cs" Inherits="Test1" %>
<%# Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<script type="text/javascript">
function delayer() {
setTimeout (function () {ShowPopUp()}, 15000);
}
delayer();
</script>
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick" Interval="1000" Enabled="true">
</asp:Timer>
<asp:Label ID="Label1" runat="server" Text="PanelNotRefreshedYet"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="ShowPopUp();" />
</form>
</body>
</html>
I think you're confused. Timer1 is a server side control. So it will fire on the server side, if you're still processing the page, that is, and will have no effect on the client side. By the time it fires in your code, the page has likely already rendered so you'll see no effect from that Timer1 object's Timer1_Tick event. Since the page has completed rendering, you can't inject new JavaScript, modify the page, or anything like that. Remember that web development is a disconnected thing. You send a request, you get a response. There are no events by nature of the web. There are libraries out there for triggering events and such but I think that's way beyond what you're trying to achieve.
For client side "timer" you need to use JavaScript setTimeout method, which you have verified as working and is the proper way for you to achieve the delay you're looking to implement.
setTimeout (function () {ShowPopUp()}, 15000);
If you still want to do it in your Alert class, then get rid of Timer1 and have your Alert class inject the timeout in JavaScript:
protected void Button1_Click1(object sender, EventArgs e)
{
Alert.Show("He heee", this);
}
And in Alert, change your script to:
string script = "<script type=\"text/javascript\">setTimeout(function() {alert('" + cleanMessage + "');}, 15000);</script>";
Your button is doing a postback, so yes the page will be refreshed and your Page_Load function will run again. You should test for this using the IsPostback property.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostback) {
Timer1.Enabled = false;
Label2.Text = "Panel refreshed at: " +
DateTime.Now.ToLongTimeString(); // Checks if page reloads
}
}
You might want to look at showing the alert using JavaScript on the page rather than running it server side tho.
<script type="text/javascript">
function showPopup()
{
alert("Hey, click something already");
}
function delayer() {
setTimeout (showPopUp, 15000);
}
delayer();
</script>
Just put your message like this. Probably easier if your logic is simple.
I am implementing a multiview using a RadioButtonList to flip its view and also AJAX.
My problem is if I set my default RadioButton (NavigateRadioButtonList.Items[0].Selected = true;), that RadioButton would become dead, ie. when I focus on it, the MultiView doesn't response at all.
This only happens in AJAX. Normal asp page doesn't have that problem.
I am at my wit's end. Can some expert help??
The code is as follow
<%# Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">
protected void Page_Init(object sender, EventArgs e)
{
for (int i = 1; i < 8; i++)
{
string RadioText = "View" + i.ToString();
NavigateRadioButtonList.Items.Add(RadioText);
Literal DescriptionTag = new Literal();
DescriptionTag.Text = "Text" + i.ToString();
View NewView = new View();
NewView.Controls.Add(DescriptionTag);
MultiViewMenu.Views.Add(NewView);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
NavigateRadioButtonList.Items[0].Selected = true;
MultiViewMenu.ActiveViewIndex = 0;
}
}
protected void ChangeView(object sender, EventArgs e)
{
MultiViewMenu.ActiveViewIndex = NavigateRadioButtonList.SelectedIndex;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:RadioButtonList ID="NavigateRadioButtonList" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ChangeView"></asp:RadioButtonList>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:MultiView ID="MultiViewMenu" runat="server">
</asp:MultiView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="NavigateRadioButtonList" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
</form>
</body>
</html>
I'm absolutliy confused.
I try to Change the default Text for a Textbox.
Here a simple Code to reproduce the Problem.
TextBox Textbox1 and the label become updated on any click to the Button.
Textbox var will never get updated. Only on first PageLoad.
The Problem is, I have to add my Textboxes from Code behind and not in aspx Page.
Any Ideas whats going on and how I can get it working?
%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="tbtester.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div >
<asp:Panel ID="mypanel" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</asp:Panel>
</div>
</form>
</body>
</html>
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace tbtester
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
System.Web.UI.WebControls.TextBox var = new System.Web.UI.WebControls.TextBox();
//if (!this.Page.IsPostBack)
Label test = new Label();
mypanel.Controls.Add(test);
mypanel.Controls.Add(var);
var.Text = DateTime.Now.ToLongTimeString();
test.Text = DateTime.Now.ToLongTimeString();
var.ReadOnly = false;
TextBox1.Text = DateTime.Now.ToLongTimeString();
}
}
}
Disable its read only flag before adding it to your panel:
TextBox var = new TextBox();
var.ReadOnly = false;
mypanel.Controls.Add(var);
Based on my current understandings, when you have an UpdatePanel control there is no full postback. Therefore if I dynamically add custom user controls and they have UpdatePanels that are updated in their code they shouldnt disappear from the page they are loaded into, right? Apparently not. I made a simple project to test and still my dynamic controls disappear when clicked even though they should not be triggering a full postback. I have an aspx page that loads the controls:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="TESTmultipleScriptManagerControls.aspx.cs" Inherits="myPlayground.TESTmultipleScriptManagerControls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
With the following code behind:
protected void Button1_Click(object sender, EventArgs e)
{
TESTcontrol1 temp = LoadControl("TESTcontrol1.ascx") as TESTcontrol1;
PlaceHolder1.Controls.Add(temp);
TESTcontrol1 temp2 = LoadControl("TESTcontrol1.ascx") as TESTcontrol1;
PlaceHolder1.Controls.Add(temp2);
}
And a simple user control:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="TESTcontrol1.ascx.cs" Inherits="myPlayground.TESTcontrol1" %>
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
</asp:ScriptManagerProxy>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
With the following code behind:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = System.DateTime.Now.ToString();
}
Any ideas on why the controls are disappearing even though there shouldnt be a postback triggering?
OK based on my current understandings, when you have an UpdatePanel
control there is no full postback.
Postbacks triggered from UpdatePanels always execute the full page life-cycle. All the events are triggered normally. It makes no difference whether you use an UpdatePanel or not. Every time you add a control programmatically you need to re-add it on every postback.
Read this post, it may help you understand a bit better what's going on here.
By End of the Page Life Cycle all the controls generated at Runtime/Compile Time will be Disposed.
Below are the Page Events. Please set the BreakPoint on each Event and you can figure out that on each Asynchronous/Synchronous Request, all these Page Events are being executed.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
}
protected override void OnPreLoad(EventArgs e)
{
base.OnPreLoad(e);
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnLoadComplete(EventArgs e)
{
base.OnLoadComplete(e);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
}
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
}
You need to populate them on each Page Init event in order to persist Viewstate, also events for controls added inside an update panel during button clicks do not seems to get registered until the next Postback. My suggestion is to keep a list of what you have added dynamically, and store it in a session variable