ASP.NET Timer Event - asp.net

protected void SubmitButtonClicked(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
---
---
//line 1
get_datasource();
String message = "submitted.";
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "popupAlert", "popupAlert(' " + message + " ');", true);
timer.Interval = 30000;
timer.Elapsed += new ElapsedEventHandler(timer_tick);
// Only raise the event the first time Interval elapses.
timer.AutoReset = false;
timer.Enabled = true;
}
protected void timer_tick(object sender, EventArgs e)
{
//line 2
get_datasource();
GridView2.DataBind();
}
The problem is with the data in the grid view that is being displayed... since when get_datasource which is after line 1 is called the updated data is displayed in the grid view since it is a postback event but when the timer event handler is calling the timer_tick event the get_datasource function is called but after that the updated data is not visible in the grid view. It is nnot getting updated since the timer_tick is not a post back event

The server-side timer as you have implemented it, will not work for what you are trying to achieve.
If you wrap both the timer and gridview in a updatepanel, the timer will trigger a postback everytime the tick event fires and you be able to update the data.
Heres a great blog post to get you going: http://mattberseth.com/blog/2007/08/using_the_ajax_timer_control_a.html
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="GridView2" runat="server">
</asp:GridView>
<asp:Timer id="Timer1" runat="server" Interval="30000" OnTick="Timer_Tick" Enabled="false" />
<asp:Button ID="Button1" runat="server" Text="Update" OnClick="SubmitButtonClicked" />
</ContentTemplate>
</asp:UpdatePanel>
Server-side code:
private void Timer_Tick(object sender, EventArgs args)
{
get_datasource();
GridView2.DataBind();
Timer1.Enabled = false;
}
protected void SubmitButtonClicked(object sender, EventArgs e)
{
String message = "submitted.";
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "popupAlert", "popupAlert(' " + message + " ');", true);
get_datasource();
GridView2.DataBind();
Timer1.Enabled = true;
}

You cannot use a timer like that. While ASP.NET tries to hide the request/response cycle of HTTP, the cycle is still there so you cannot just do whatever you like in your postback: you still need to understand that a HTML response is being sent back in response to a HTTP request.
Is there any particular reason why you're trying to use a timer like this? It doesn't seem to make sense to me. What is it that you're trying to achieve?

Related

Repeater with Buttons doesn't fire OnItemCommand even when DataBind doesn't happen when IsPostBack is true

I've got an image button in a Repeater, which is in a User Control, and I can't get the OnItemCommand event to fire when I click it. It always gives the error: "... Invalid postback or callback argument. Event validation is enabled using ..."
When I change the image button to a link button, it doesn't give me the error, but it still doesn't fire the OnItemCommand function.
I found some other relevant answers (such as How to process events from Buttons inside Repeaters? And what's this EnableEventValidation thing?) but they all say, "Make sure you're data-binding your repeater inside of a if(!Page.IsPostBack) block." I have done that, but it didn't make a difference.
Here's the markup for the repeater:
<asp:Repeater ID="rptExpenses" OnItemDataBound="rptExpenses_ItemDataBound" OnItemCommand="Button_Command" runat="server" >
<ItemTemplate>
<asp:ImageButton ID="ibDelete" ImageUrl="~/Images/delete.png" CommandName="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
Here's some exerpts from the code-behind
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void rptExpenses_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem)) {
var ibDelete = (ImageButton)e.Item.FindControl("ibDelete");
ibDelete.CommandArgument = e.Item.DataItem.ToString();
}
}
protected void Button_Command(object sender, EventArgs e) {
var btn = (IButtonControl)sender;
switch (btn.CommandName) {
case "Delete":
//delete it
break;
}
}
Try using this code instead:
<asp:Repeater ID="rptExpenses" runat="server">
<ItemTemplate>
<asp:ImageButton ID="ibRemove" ImageUrl="~/Images/delete.png" runat="server"
CommandName="Remove"
CommandArgument='<%# Container.DataItem %>'
OnCommand="ibRemove_Click"/>
</ItemTemplate>
</asp:Repeater>
And this in the code behind:
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void ibRemove_Click(object sender, CommandEventArgs e)
{
var btn = (IButtonControl)sender;
switch (btn.CommandName)
{
case "Remove":
//delete it, use btn.CommandArgument to find id to remove
break;
}
}
If you still receive the ... Invalid postback or callback argument. Event validation is enabled using ... error, it most likely means that you are somewhere re-binding the repeater before the ibRemove_Click(...) event is raised.
I found the reason why this was happening in the answer to this question: Why ItemCommand doesn't fired on My Repeater
Turns out that for some reason the Page's DataBind function was invalidating the repeater's controls without passing through the repeater's OnItemDataBound function a second time.

How to avoid TextChanged event in ASP.NET

I have a TextBox and a postback Button.
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged1" EnableViewState="false"></asp:TextBox><span></span>
<asp:Button ID="Button1" runat="server" Text="Button" />
So, I need to fire TextChanged event only when text changed(what an irony), like it fires when EnableViewState is true. I can't unsubscribe event or subscribe it somwhere else or enable ViewState.
I've tried to save text from the TextBox in HiddenField and then check if it's changed. Here's the code
protected void Page_Load(object sender, EventArgs e) {
if (HiddenField1.Value != TextBox1.Text) {
HiddenField1.Value = TextBox1.Text;
TextBox1.Text = HiddenField1.Value;
}
}
But I have no idea what to do when text is not changed and not to fire the event.
The problem was in saving values from TextBox when ViewState disabled. Saving it in HiddenField is not a good idea, because we can take value from HiddenField on Page_Load, but we need to take it on TextBox init. However, if we save TextBox to Session variable, this problem will disappear. Here's the code:
protected void TextBox1_TextChanged1(object sender, EventArgs e) {
Session["text"] = TextBox1.Text;
}
protected void TextBox1_Init(object sender, EventArgs e) {
if(Session["text"]!=null)TextBox1.Text = Session["text"].ToString();
}
Save values in session variable on textchanged event and restore it on textbox init. Comparison run on framework level.

Adding dynamic buttons to updatepanels and tieing in onclick event ASP.net Webforms

I got a query regarding adding dynamic buttons with dynamic onclick events on a set of updatepanels.
I've simplified the scenario as the code I have so far is way too long and tied up..I've created a test page with 3 update panels.
In terms of the actual page the first updatepanel will be for the filters which will in turn update the second update panel. 2nd update panel will consist of all the results, depending on filters..this will be a table of buttons.
On the click of any of these buttons on the second update panel, depending on the ID of the button the results will be generated in the last update panel.
The problem I'm facing is tieing in the button click event when the buttons are created.
When I create the button from the onclick from the first update panel, it adds it to the placeholder but the click event does not fire at all.
Here is some code from my testing page.
test.aspx
<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" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" ChildrenAsTriggers="False"
UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder id="ph2" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder id="ph3" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Button up2button = new Button();
up2button.ID = "up2button";
ph2.Controls.Add(up2button);
up2button.Click += new EventHandler(up2button_Click); // Not being registered?
AsyncPostBackTrigger trigger1 = new AsyncPostBackTrigger();
trigger1.ControlID = "up2button";
trigger1.EventName = "Click";
UpdatePanel2.Triggers.Add(trigger1);
ScriptManager1.RegisterAsyncPostBackControl(up2button);
UpdatePanel2.Update();
}
protected void up2button_Click(object sender, EventArgs e) { //and not being fired
Button up3button = new Button();
up3button.ID = "up3button";
up3button.Click += new EventHandler(up3button_click);
ph3.Controls.Add(up3button);
AsyncPostBackTrigger trigger1 = new AsyncPostBackTrigger();
trigger1.ControlID = "up3button";
trigger1.EventName = "Click";
UpdatePanel3.Triggers.Add(trigger1);
UpdatePanel3.Update();
}
protected void up3button_click(object sender, EventArgs e) {
}
}
Thankyou for your time.
here's a quick sample, I find on the internet:
I've used a placeholder to hold the dynamically created controls - the button and textboxes on that button's click event.
and the code:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (ViewState["Add"] != null)
{
Button add = new Button();
add.Text = "Add";
add.Click += new EventHandler(add_Click);
PlaceHolder1.Controls.Add(add);
}
if (ViewState["textboxes"] != null)
{
int count = 0;
count = (int)ViewState["textboxes"];
for (int i = 0; i < count; i++)
{
textbox textbox_foradd = new TextBox();
textbox_foradd.ID = "textadd" + (i + 1).ToString();
PlaceHolder1.Controls.Add(textbox_foradd);
}
}
}
}
void add_Click(object sender, EventArgs e)
{
int count = 1;
if (ViewState["textboxes"] != null)
{
count += Convert.ToInt32(ViewState["textboxes"]);
}
TextBox textbox_foradd = new TextBox();
textbox_foradd.ID = "textadd" + count.ToString();
PlaceHolder1.Controls.Add(textbox_foradd);
ViewState["textboxes"] = count;
}
protected void Button1_Click(object sender, EventArgs e)
{
Button add = new Button();
add.Text = "Add";
PlaceHolder1.Controls.Add(add);
ViewState["Add"] = 1;
}
Also, you need to give unique ID to each control in case you add multiple of the same control.
Ex:
Add button with id 'ButtonA'
Add another button with id 'ButtonA'
will fail, after the postback your buttons will trigger the event properly, but the action will not do a proper refresh.
Making it looks like it is not refreshing anymore.
Instead generate a unique ID for each control you add dynamically (and save those IDs).
In the postback, recreate those controls and reassign the IDs properly.
Only then will the UI refresh properly.

Dynamic creation of Button OK but its event handler NOT executed?

I have following simple controls on a page
WebForm1.aspx
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
<br />
<asp:Label ID="lblContent" runat="server" ></asp:Label>
Some code behind in WebForm1.aspx.cs :
protected void Page_Load(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "btnTest";
btn.Text = "I was dynamically created";
btn.Click += new EventHandler(btnTest_Click);
Panel1.Controls.Add(btn);
}
void btnTest_Click(object sender, EventArgs e)
{
lblContent.Text = "btnTest_Click: " + DateTime.Now.ToString();
}
In short, when I dynamically create a Button (btnTest) in the Page_Load event and assign event handler btnTest_Click to the button. Click event then, when loading the page I see btnTest appearing and when clicking on it the event handler btnTest_Click is invoked. OK, No problem.
I have a problem though when I try following scenario... first, I add a button to the page in designer mode.
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
<asp:Button ID="btnCreateDynamically" runat="server"
Text="Create Button Dynamically"
onclick="btnCreateDynamically_Click" />
<br />
<asp:Label ID="lblContent" runat="server" ></asp:Label>
I move the code from Page_Load to the button event handler of btnCreateDynamically as follows
protected void btnCreateDynamically_Click(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "btnTest";
btn.Text = "I was dynamically created";
btn.Click += new EventHandler(btnTest_Click);
Panel1.Controls.Add(btn);
}
When running the WebApp now and clicking on btnCreateDynamically, btnTest is created but when I click on btnTest its event handler is NOT invoked ???
Why not?
How can I make this work?
You should add the dynamic controls in the Page's Init event handler so that the ViewState and Events are triggered appropriately.
Try doing this:
protected void Page_Init(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "btnTest";
btn.Text = "I was dynamically created";
btn.Click += new EventHandler(btnTest_Click);
Panel1.Controls.Add(btn);
}
You need to re-create dynamic control on each postback, see my previous answer to a similar question here

Setting viewstate on postback

I am trying to set a ViewState-variable when a button is pressed, but it only works the second time I click the button. Here is the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
lblInfo.InnerText = String.Format("Hello {0} at {1}!", YourName, DateTime.Now.ToLongTimeString());
}
}
private string YourName
{
get { return (string)ViewState["YourName"]; }
set { ViewState["YourName"] = value; }
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
YourName = txtName.Text;
}
Is there something I am missing? Here is the form-part of the design-file, very basic just as a POC:
<form id="form1" runat="server">
<div>
Enter your name: <asp:TextBox runat="server" ID="txtName"></asp:TextBox>
<asp:Button runat="server" ID="btnSubmit" Text="OK" onclick="btnSubmit_Click" />
<hr />
<label id="lblInfo" runat="server"></label>
</div>
</form>
PS: The sample is very simplified, "use txtName.Text instead of ViewState" is not the correct answer, I need the info to be in ViewState.
Page_Load fires before btnSubmit_Click.
If you want to do something after your postback events have fired use Page_PreRender.
//this will work because YourName has now been set by the click event
protected void Page_PreRender(object sender, EventArgs e)
{
if (Page.IsPostBack)
lblInfo.InnerText = String.Format("Hello {0} at {1}!", YourName, DateTime.Now.ToLongTimeString());
}
The basic order goes:
Page init fires (init cannot access ViewState)
ViewState is read
Page load fires
Any events fire
PreRender fires
Page renders

Resources