Null after onClick action - asp.net

I'm starting with asp.net, but i'm not quite sure what am I doing wrong. Actually my first step in asp is to make a calculator but after 2h of looking for answer i've decided to ask you about that.
I have 10 buttons with [0,1,2...9], 4 action buttons [+,-,*,/] and one button to calculate [=]:
int firstNumber, secondNumber;
Button lastClicked;
bool isFirstNumberSet;
protected void Page_Load(object sender, EventArgs e)
{
firstNumber = 0;
isFirstNumberSet = false;
lastClicked = new Button();
}
public void addToTextbox(object sender, EventArgs e)
{
Button number = (Button)sender;
TextBox1.Text += number.Text;
}
public void doSomething(object sender, EventArgs e)
{
if (isFirstNumberSet.Equals(false)) firstNumber = int.Parse(TextBox1.Text);
else secondNumber = int.Parse(TextBox1.Text);
lastClicked = new Button();
lastClicked = (Button)sender;
isFirstNumberSet = true;
TextBox1.Text = "";
}
public void calculate(object sender, EventArgs e)
{
switch (lastClicked.ID)
{
case "ButtonPlus":
TextBox1.Text = (firstNumber + secondNumber).ToString();
isFirstNumberSet = false;
break;
case "ButtonMinus":
TextBox1.Text = (firstNumber - secondNumber).ToString();
isFirstNumberSet = false;
break;
case "ButtonDziel":
TextBox1.Text = (firstNumber / secondNumber).ToString();
isFirstNumberSet = false;
break;
case "ButtonMnoz":
TextBox1.Text = (firstNumber * secondNumber).ToString();
isFirstNumberSet = false;
break;
}
but when i do for example action like 2 + 2, and after that i hit "=". I get an exception about that code:
switch (lastClicked.ID)
It says that lastClicked is null, but how? after hit "+" this should save sender object to this variable. Am i wrong?

Your button variable assignment does not persist between postbacks the way you are expecting. When calculate fires upon your "=" keyhit, lastClicked is now unassigned on this new "round trip," and thus null. When you press one button once, then a second button the next time, there's no memory of the previous hit unless you store the value in a field that's captured in the data sent back to the server.
One approach you could explore involves storing the operation that's been selected into a hidden HTML field on your form, and then interrogate that upon hitting the calculate routine. That eliminates the need to try persisting the "lastClicked" button as you have.
Somewhere in your aspx, within your form, you could add:
<asp:HiddenField id="Operation" runat="server" />
Then, in your codebehind in response to one of your operator buttons:
Operation.Value = "Plus"; // or "+" or whatever is appropriate
That would then get sent back down to the client on the next trip, and then be part of the data sent back to the server when your calculate method is called in response to the "=" button click:
public void calculate(object sender, EventArgs e){
switch(Operation.Value){
case "Plus";
// do the "PLUS" thing
// and so on
... (snip)...
}

Related

Page_PreLoad() event is triggered before link button click event when I click on a link button

I'm listing folders and files in drive E, I'm using a hidden field to keep the path, I created some link buttons representing folders, they are created programmatically on Page_PreLoad() event:
protected void Page_PreLoad(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(hdfPath.Value))
{
path = "E:\\" + hdfPath.Value;
directories = Directory.GetDirectories(path);
files = Directory.GetFiles(path);
}
else
{
directories = Directory.GetDirectories("E:\\");
files = Directory.GetFiles("E:\\");
}
for (int i = 0; i < directories.Length; i++)
{
LinkButton lkbLink = new LinkButton();
lkbLink.Click += new EventHandler(btn_Click);
void btn_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(hdfPath.Value))
hdfPath.Value = folderName;
else
hdfPath.Value += "\\" + folderName;
}
}
}
When I click in whichever link button, first of all Page_PreLoad() event is triggered then btn_Click() event, while I expected btn_Click() to be fired first. In that case the related value on hidden field belongs to the value of one step before.
Is something wrong with the ASP.Net life cycle I chose?
How can I make it immediately set the hidden filed value when user clicks on the link button so that the (correct) current value on hidden field be taken?
There is nothing wrong with the lifecycle and you can not choose a lifecycle either :)
The PreLoad-Event of the page is always before the control-events.
This will give you a detailed overview over the lifecycle in asp.net.
It's a little complicated in your case:
you need to add some buttons dynamically and attach event handlers to them - this has to be done on every postback, else the button-handlers won't be triggered.
Then in your handler you need to delete these before added buttons again and add the new ones according to the new path.
To achieve this, make a method from your code, e.g:
private void InitButtons()
{
if (!string.IsNullOrEmpty(hdfPath.Value))
{
path = "E:\\" + hdfPath.Value;
directories = Directory.GetDirectories(path);
files = Directory.GetFiles(path);
}
else
{
directories = Directory.GetDirectories("E:\\");
files = Directory.GetFiles("E:\\");
}
for (int i = 0; i < directories.Length; i++)
{
LinkButton lkbLink = new LinkButton();
lkbLink.Click += new EventHandler(btn_Click);
void btn_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(hdfPath.Value))
hdfPath.Value = folderName;
else
hdfPath.Value += "\\" + folderName;
// remove the old buttons here, if you need to
// RemoveOldButtons();
// call the Init-Buttons-Function again
InitButtons();
}
}
}
Call this method from your button event-handlers as shown above and again in your load-event-handler:
protected void Page_PreLoad(object sender, EventArgs e)
{
InitButtons();
}

asp.net textbox not updated from another task

I have a GridView and on its SelectedIndexChanged the code is fired:
protected void grdEntry_SelectedIndexChanged(object sender, EventArgs e)
{
lblAssignId.Text = grdEntry.SelectedRow.Cells[1].Text == " "
? ""
: grdEntry.SelectedRow.Cells[1].Text;
Ob.BranchId = Globals.BranchID;
Ob.AssignId = lblAssignId.Text;
DataSet dsMain = GetAssignDetails(Ob);
if (dsMain.Tables[0].Rows.Count != 0)
{
// some other code
Task.Factory.StartNew(() => FillMemberShipAndBarCode(dsMain.Tables[0].Rows[0]["CustomerCode"].ToString(), Ob.BranchId));
}
}
and the code for filling membership id is
private void FillMemberShipAndBarCode(string customerCode, string branchId)
{
var sqlCommand = new SqlCommand
{
CommandText = "sp_customermaster",
CommandType = CommandType.StoredProcedure
};
sqlCommand.Parameters.AddWithValue("#CustomerCode", customerCode);
sqlCommand.Parameters.AddWithValue("#BranchId", branchId);
sqlCommand.Parameters.AddWithValue("#Flag", 18);
var data = PrjClass.GetData(sqlCommand);
txtMemberShip.Text = data.Tables[0].Rows[0]["MembershipId"].ToString();
txtBarCode.Text = data.Tables[0].Rows[0]["Barcode"].ToString();
}
It's working fine, but is is not updating any of the textboxes. Also, I checked in watch window, the values are returned as expected (M-1213 and 634-98-4 ) and the code does reaches the point txtMemberShip.Text = data.Tables[0].Rows[0]["MembershipId"].ToString();
but the txtMemberShip just remains empty??? Can anyone tell me why is not updating the textboxes?
UPDATE
As per comments, here is the page load
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindDropDown();
BindGrid();
SetDefaultsInTextBoxes();
}
}
And I don't have any code that waits on this task.
Don't do this:
Task.Factory.StartNew(() => FillMemberShipAndBarCode(dsMain.Tables[0].Rows[0]["CustomerCode"].ToString(), Ob.BranchId));
What are you trying to achieve by doing so?
What is probably happening is your method FillMemberShipAndBarCode is probably running after ASP.NET has already sent the page back to the browser. Thus, essentially, no visible effect on the rendered HTML.
ASP.NET isn't a good place to do multi-threaded stuff.
Try just replacing the above with this:
FillMemberShipAndBarCode(dsMain.Tables[0].Rows[0]["CustomerCode"].ToString(), Ob.BranchId);

ASP.net : textChange Partial Update for programmatically inserted textboxes

I trying get some programmatically inserted textboxes (inserted into a gridview) to do a textChange partial update. It is sort of working but it does not automatically calls textEntered() method after I typed some text in these textboxes. I got a clue that I might need to use AJAX and things like updatepanels but I just don't fully understand how they will work in the context of what I am trying to do.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (!e.Row.Cells[4].Text.Equals(" ") && firstTime == false)
{
TextBox tb = new TextBox();
tb.Text = e.Row.Cells[4].Text;
tb.TextChanged += new EventHandler(textEntered);
textBoxArray.Add(tb);
int length = textBoxArray.Count - 1;
tb = (TextBox)textBoxArray[textBoxArray.Count - 1];
e.Row.Cells[4].Text = null;
e.Row.Cells[4].Controls.Add(tb);
Cache["textBoxArray"] = textBoxArray;
} firstTime = false;
}
protected void textEntered(object sender, EventArgs e)
{
lbl_test.Text += "test";//This line is for testing purposes
}
auto postback of textbox is true or false? make it true.

Wire up button created at runtime

Im creating some buttons based on a value of some runtime variable (i dont even know how many).
My code for the button is as follows:
Button cancel = new Button();
cancel.Text = "Cancel";
cancel.ID = "cancelEnrollmentForStudent" + zapsanePredmetyList.ElementAt(i).ID.ToString() + "-" + i ;
cancel.Click += new EventHandler(cancelEnrollment);
string toCancel = selectedSubject.SelectedValue + ";" + studentToEnroll.SelectedValue;
cancel.CommandArgument = toCancel;
while the code for the click method is
protected void cancelEnrollment(object sender, EventArgs e)
{
//do something when button clicked.
Button sourceButton = (Button)sender;
string[] data = sourceButton.CommandArgument.Split(';');
}
However, the click method is not firing up when the button is clicked. I suppose this has something to do with the fact, that I build the button at runtime. Cld someone advise on how to get this method fire up?
Thanks,
Ondrej
You have to override OnInit add the code in OnInit method.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Button btn = new Button();
btn.ID = "btn1";
btn.Text = "Button1";
btn.Click += new EventHandler(btn_Click);
this.form1.Controls.Add(btn);
}
void btn_Click(object sender, EventArgs e)
{
Button bt = (Button)sender;
bt.Text = "Changed";
}

Call a button_click on page_load asp.net

I have a search textbox and a search button, when clicked displays a grid with the following names and gender.However I have redirected the page to another page on edit.Now When I comeback from that page to the page containing the gridview I want to display the same search again. I have successfully put retrieved the information but storing it into session, but I'm not able to call my btn_click event # page_Load.
Here's a snippet:
EDIT: I have made some changes in my code
protected void Page_Load(object sender, EventArgs e)
{
if (Session["Redirected"] != null)
{
if (Session["FirstName"] != null)
txtSearch.Text = Session["FirstName"].ToString();
if (Session["Gender"] != null)
ddlGen.SelectedValue = Session["Gender"].ToString();
btnSearch_Click(sender, e);
}
if (!Page.IsPostBack)
{
BindGrid();
}
}
and here's the click event:
protected void btnSearch_Click(object sender, EventArgs e)
{
string query = "Select EmployeeId,FirstName,Password,Address,sex,Deptno,act_book,actTV,DOJ,isActiveYN from employees where 1=1";
if (txtSearch.Text != "")
{
query += " and FirstName like '%" + txtSearch.Text + "%'";
Session["FirstName"] = txtSearch.Text;
}
if (ddlGen.SelectedValue != "")
{
query += " and sex='" + ddlGen.SelectedValue.ToUpper() + "'";
Session["Gender"] = ddlGen.SelectedValue;
}
DataSet ds = new DataSet("Employees");
SqlConnection con = new SqlConnection("Password=admin;User ID=admin;Initial Catalog=asptest;Data Source=dbsvr");
SqlDataAdapter da = new SqlDataAdapter(query, con);
da.Fill(ds);
gvSession.DataSource = ds;
gvSession.DataBind();
}
Now I'm able to save search, so that problem is resolved ,but another has poped up that when I click the button search after changin text it takes me back to the older search..The reason is probably because sessions are not cleared,but I did that as well by handling textchanged and selectedindexchanged eventd.
Rather than trying to call your button click handler from the Page_Load, change your button click handler to simply call another method like:
protected void btnSearch_Click(object sender, EventArgs e)
{
RunSearch();
}
Then move all your btnSearch_Click() code into RunSearch()
Then in your Page_Load you can do something like:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["Gender"] != null && Session["FirstName"] != null)
{
txtSearch.Text = Session["FirstName"].ToString();
ddlGen.SelectedValue = Session["Gender"].ToString();
RunSearch();
}
if (!Page.IsPostBack)
{
BindGrid();
}
}
On a side note, I would recommend taking a look into SQLCommand Parameters. Your code is prone to SQL Injection Attacks:
http://en.wikipedia.org/wiki/SQL_injection
You should reset the session redirected variable so it doesn't fall in the same case.
protected void Page_Load(object sender, EventArgs e)
{
if (Session["Redirected"] != null)
{
Session["Redirected"] = null;
....
You can do using an QueryString paremeter when page return back to main page then here you can check QueryString paremeter is exist. here you can implement code for bind grid
if (Request.QueryString["Back"]!= null)
{
// Your bind grid function
}
You can create a function, which will called both from the button_click and page_load.

Resources