Image Button and post back issue - c#

I have two image buttons with Click events assigned to them. There is code in each event. When they are clicked it runs the page load function before it runs the code in the click events. How can i get it to run the code in the click events first?
Happy Holidays!
Image buttons.
protected void Page_Load(object sender, EventArgs e)
{
//YesID = "1";
if (!IsPostBack)
{
Session["FirstyesID"] = 0;
Session["FirstnoID"] = 0;
Session["SecondnoId"] = 0;
Session["SecondyesId"] = 0;
Session["yesID"] = 0;
Session["noId"] = 0;
}
else
{
//Run this code
}
}
protected void FirstPicLink_Click(object sender, ImageClickEventArgs e)
{
Session["yesID"] = Session["FirstyesID"];
Session["noId"] = Session["FirstnoID"];
//FirstPicLink.PostBackUrl = "default.aspx";
//FirstPicLink.PostBackUrl = "GadgetFS.aspx?yesId=" + firstYesPicId + "&noId=" + firstNoPicId;
}
protected void SecondPicLink_Click(object sender, ImageClickEventArgs e)
{
Session["yesID"] = Session["SecondyesId"];
Session["noId"] = Session["SecondnoId"];
//SecondPicLink.PostBackUrl = "default.aspx";
//SecondPicLink.PostBackUrl = "GadgetFS.aspx?yesId=" + secondYesPicId + "&noId=" + secondNoPicId;
}

What you are asking is illegal. There's an order in which things are executed in ASP.NET
ASP.NET Page LifeCycle Overview
As you can see "Postback event handling" happens after "Load" and trying to trick this, will cause you headaches afterwards. It's a very bad practice and this is coming from someone who's been down that road. You don't want to mess with the page lifecycle.
Looking at your code, I could suggest you put whatever should go in the // Run this code lines into a method, and call that method from the Click handlers, but not from the else block.
Anyhow, you should always have the page lifecycle in mind, and revise your code logic according to that.

Related

Button Click counter + textbox

I'm new to C# and visual studio, I started learning recently...at the moment I'm trying to make one button that counts the number of clicks and a text box which you can type in any number and it will be reflected in the button counter while adding 1, right now it works but I want the button to add 1 every time you click, here is my code,
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MainWeb1
{
public partial class ButtonCounter : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Text = (TextBox1.Text);
btn.Text = (Int32.Parse(btn.Text) + 1 ) .ToString();
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
string var;
var = TextBox1.Text;
}
}
}
You need to separate the counter on the button from the value that you get from the textbox and recalculate the button text using the updated values.
In an ASP.NET, the class instance of a page is recreated whenever an event happens that requires a callback to the server. You can see this behavior easily if you put a breakpoint inside the page constructor.
So you need something that keeps around the state of your counter between each click. There are many possibilities, hidden fields, static variables or session variables.
A possible approach using a static variable:
public partial class ButtonCounter : System.Web.UI.Page
{
// keeps the count of the clicks on the button
private static int btnCounter;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
btnCounter++;
Button btn = (Button)sender;
btn.Text = (Int32.Parse(TextBox1.Text) + btnCounter ) .ToString();
}
But static variables have some troublesome aspects in ASP.NET apps. They are shared between all users, so a new user will see the counter value reached from the clicks from another user. If, for any reason, the IIS server needs to recycle the application pool, the static variables are lost and they restart from 0.
The Session instead is a memory area assigned to the current user where one can store values or references to information that needs to be kept around until the session ends. So a solution through a Session variable could be
protected void Button1_Click(object sender, EventArgs e)
{
int btnCounter = 0;
if(Session["counter"] != null)
counter = Int32.Parse(Session["counter"]);
counter++;
Session["counter"] = btnCounter;
Button btn = (Button)sender;
btn.Text = (Int32.Parse(TextBox1.Text) + btnCounter ) .ToString();
}
A simpler solution is through the use of an HiddenField control where you keep the counter and use it more or less like the Session example above.
protected void Button1_Click(object sender, EventArgs e)
{
int btnCounter = Int32.Parse(hiddenCounter.Text);
btnCounter++;
hiddenCounter.Text = btnCounter.ToString();
Button btn = (Button)sender;
btn.Text = (Int32.Parse(TextBox1.Text) + btnCounter ) .ToString();
}
This will work because ASP.NET keeps a ViewState for all the controls in your page reinitializing them with the previous values (and this is not so good as it seems because it augments the information that needs to be exchanged between the server and the client)
If you really still want to work with ASP.NET it is of uttermost importance to understand the ASP.NET Page Life cycle but remember that this is an obsolete technology for Microsoft. All the new enhancements are in the realm of ASP.NET Core and the new programming models like ASP.NET MVC and ASP.NET Razor pages.

managing and controlling the post back priority

I have a web page which is contained a Data Filter and a report.The Data Filter is a user control. The report is loaded inside the main page so totally i have two pages. one user control and one web page.
Now i am going to gather the data by clicking a button inside the user control then i can use it to filter the table, but it seems that during the post back it goes first to the Page_Load method of the main, not the user control so the report is constructed before filtering.The BtnPreviewReport_Click must be executed earlier than the page_Load.
What should i do ?
User control
protected void BtnPreviewReport_Click(object sender, EventArgs e)
{
Date = Year.Text + "/" + Month.Text + "/" + Day.Text;
}
Main Page
protected void Page_Load(object sender, EventArgs e)
{
string date = UserControls1.Date;
Response.Write(date);
}
Output : Nothing
I am not sure why the ButtonClick event should be run earlier than page load.
But here's a simple way to solve your question:
private bool isPageLoaded = false;
private bool isButtonClicked = false;
private void ButtonClick()
{
isButtonClicked = true;
doTheFirstThing();
if( isPageLoaded )
{
doTheSecondThing();
}
}
private void PageLoad()
{
isPageLoaded = true;
if( isButtonClicked )
{
doTheSecondThing();
}
// else let the button click handle the SecondThing()
}

Why can't I get the value from textbox?

I've just started learning ASP.NET and I'm facing a problem with getting textbox values. I want to do a simple calculator with only 4 basic operations but what happens is that after I click the + sign and click Go, I see that I didn't store the first number at all. Second number is fine though. Here is a sample of my code.
public partial class deafult : System.Web.UI.Page
{
public TextBox output = new TextBox();
public double temp,tempAdd, calc;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
tempAdd = Convert.ToDouble(output.Text);
output.Text = String.Empty;
}
//User enters another number after clicking Add button then clicks Proc
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
}
I debugged and tempAdd is always 0 but I get the number in temp. temp variables and calc is defined public.
You essentially have the problem with all of your variables being re-initialized on load of the page. Unlike winforms, web is stateless.
There are ways of persisting state between refreshes, however. The most obvious choice for your application would be to only go to the server once with the both values and what you want to do with them. ie One button click.
However, for personal edification, it may be worth looking up ViewState. This allows you to store values in an array of sorts and retrieve them even after a refresh.
There are also Session and Application level arrays in ASP.NET that work in similar ways.
Every time you call the page (by events) all your properties is initialized.
Try to do all your logic in one event or store your properties in manager / service / db.
In web (Asp.Net) on every postback properties will get cleared, try to use ViewState or Session variables to hold these values. Refer Asp.Net State Management concepts from MS.
Hope this may help you.
Web controls are State less so you should user session sate to hold the first value then do your stuff...
Ex:-
protected void btnAdd_Click(object sender, EventArgs e)
{
Session["tempAdd"] = output.Text;
output.Text = String.Empty;
}
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
string oldval=Session["tempAdd"] != null ?Session["tempAdd"].ToString() :"";
if(oldval!="")
tempadd=Convert.ToDouble(oldval);
calc = tempAdd + temp;
output.Text = calc.ToString();
}

Updating the ViewState before the Load event of the page

Is there any way to update the ViewState from a page event (such as a button click) BEFORE the Load event of the page?
I understand that the event handlers only get called after the load events, but is there any way around this?
Due to the life-cycle of an ASP .net page. The only way to pass state to the server that can be accessed OnPageLoad is by using a HiddenField on the page which is updated on the client-side with Javascript.
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["val"] != null)
{
int s = Convert.ToInt32(ViewState["val"]);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (ViewState["val"] != null)
{
int s = Convert.ToInt32(ViewState["val"]);
s = s + 5;
ViewState["val"] = s;
}
else
{
ViewState["val"] = 6;
}
}
This is the code i tested on my machine
and on page load i am getting the updaetd value each time,

How can I load the Same ASP Grid View with different conditions?

I have a DDL and a ASP .net Grid view in my aspx page. I have two methods getALLProgram and getProgramBy name, both are working fine. My problem is: when the page is loaded for the first time, I want to call the getAllprogram method, after that if a User selects a program from DDL I want my getprogramByname method to be called.
How here is my code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindProgramDDL();
BindGrid();
}
//BindProgramDDL();
}
protected void BindGrid()
{
string strProgramCode = DDLProgram.SelectedIndex.ToString();
List<FormGridEntity> gridEntities = new List<FormGridEntity>();
GridForResult.DataSource = gridEntities;
GridForResult.DataBind();
//throw new NotImplementedException();
}
protected void BindProgramDDL()
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
DDLProgram.DataSource = programEntities;
DDLProgram.DataTextField = "Shortname";
DDLProgram.DataValueField = "Id";
DDLProgram.DataBind();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
protected void OnDDLProgramChanged(object sender, EventArgs e)
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
The Code is incomplete. i am still working on it. But I not getting the logic How will I make this happen that I have told you here. I hope I made my question clearly, if it confusing, please let me know what else I should provide here.
You should check in your BindGrid if any program has been selected or not and route the call as per that. For example,
protected void BindGrid()
{
...
if (DDLProgram.SelectedIndex >= 0)
{
// program selected
var programCode = DDLProgram.SelectedValue;
data = GetProgramByName(programCode);
}
else
{
// get all programs
data = GetAllPrograms();
}
// bind data with grid
}
You can either call BindGrid in page_load unconditionally (i.e. in post-back scenarios also) or invoke it on your DDL change.
how about writing getProgramByname on a selected index changed event of a drop down list and getALLProgram on page load event ?
I hope, I was clear on what your doubt and the above mentioned suggestion did helped.
Just change these 2 things
protected void BindGrid()
{
List<FormGridEntity> gridEntities = (DDLProgram.SelectedIndex==-1)
?FormSaleSubmit_BAO.GetAllPrograms()
:FormSaleSubmit_BAO.GetProgramByName(DDLProgram.SelectedValue);
GridForResult.DataSource = gridEntities;
GridForResult.DataBind();
}
protected void OnDDLProgramChanged(object sender, EventArgs e)
{
BindGrid();
}

Categories

Resources