The purpose of this handler is simply to place a "0" in quantityTextBox when the page first loads (plus some JS to remove and replce the "0" in response to muse behaviour).
The purpose of this handler is simply to hide the product_id from view.
// AT EACH "Add To Quote" BUTTON CLICK...
protected void familyGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
GridViewRow row = ((System.Web.UI.WebControls.GridView)(sender)).Rows[int.Parse(e.CommandArgument.ToString())];
string idString = row.Cells[0].Text;
int id = Convert.ToInt32(idString);
string codeString = row.Cells[1].Text;
int parentid = id - 1;
int quantity = Convert.ToInt32(((TextBox)row.FindControl("quantityTextBox")).Text);
if (quantity < 1)
{
Response.Redirect(Request.RawUrl);
}
.
.
This handler controls the addition of the product (and its quantity) to the shopping cart.
**********
My problem is that no matter what the user chooses as a quantity in quantityTextBox, this line:
int quantity = Convert.ToInt32(((TextBox)row.FindControl("quantityTextBox")).Text);
always returns "0" and, hence, the if statement that immediately follows this line simply refreshes the page and nothing further happens.
I have debugged the program flow and I know why the value is "0" but I cannot understand why the program flow is like it is.
Here's why. Upon browsing to the page:
Page_Load,
RowDataBound,
RowCreated: a zero is placed in quantityTextBox,
RowDataBound 2,
RowCreated 2,
RowDataBound 3,
RowCreated 3,
RowDataBound 4,
RowCreated 4, .... there are 4 rows on the GridView.
Here, I am sent back to the page (from VisualStudio debugger), and I enter a quantity in quantityTextBox fro row 1 and hit that row's button. Then:
RowCreated: THIS IS THE PROBLEM... what I put in quantityTextBox has now been replaced with a zero. Why has the code taken me here? (Again, this loops through the four rows putting zeros in them all).
Page_Load,
Numbers 2 to 9 from above,
Finally: where I expected to come straight, RowCommand.
By the time the code runs in RowCommand, the value in quantityTextBox is zero, ALWAYS.
How can I avoid the button click running through the RowCreated code?
When ASP.Net pages postBack, the entire page is recreated. Your rows are therefore recreated and RowCreated will be hit. The data for the gidview should be persisted in the view state and grid should be bound to that data, unless you explicity tell it not
to which you do by saying quantityTB.Text="0";. Try to wrap that code in:
Sorry, I thought you'd hit the nail on the head here.
The code actually makes no difference.
Any other ideas?
I have this code working now but the way I got it to work was to take out the C# databinding and use a SqlDataSource instead. The C# is in Page_Load but the quantityTextBox is a stand-alone TemplateField, not a value of 0 pulled from the database so this
shouldn't overwrite the user's choice of quantity, should it?
Just as msmk said——Microsoft only makes to simplify programming of asp.net programming, so it seems that you are developing on WinForm. But in fact, you should know that Html page is of NON-MEMORY,
which means it cannot remember what you have given to itself after twice submitting. This just depends on HiddenField (In C# ViewState takes the action).
So you cannot let page remember what you've inputted, and each time you have to (either will be ok).
1) Use js to assign one-by-one textboxes values, even if when the page submitted again and refereshed, it will automatically "remember" things.
2) In the event of RowDataBound, just change the textbox values.
Thank you for the advice: I always prefer to learn than to copy and paste.
Can you, however, explain why the same code works perfectly if I bin the GV to a SqlDataSource in MarkUp but does not work if I bind it to a SqlDataAdapter in CodeBehind (binding posted above)?
I prefer to bind in CodeBehind as I can make the GV NOT SHOW if there is no data to display.
Sorry, I think you misunderstood my question. I know how to hide the GV.
My question is why the my code to grab the value of the quantity text box works if I bind the GV to a SqlDataSource but not if I bind it to a SqlDataAdapter in C#. I'd really like an answer to this as I prefer to use C# for binding.
Would you like me to post complete code of version that works and version that doesn't?
Can you, however, explain why the same code works perfectly if I bin the GV to a SqlDataSource in MarkUp but does not work if I bind it to a SqlDataAdapter in CodeBehind (binding posted above)?
Hi again,
If you do data-binding yourself, Just like what I say above, Html isn't of NON-Memoryable, which means once you bind data in the Page_Load event, and when you refresh the whole page, the GridView will be re-newed (re-created again). this will make you lose
all of your previous data contents. So if you are using SqlDataSource, when you refresh the page, it will fetch all the data contents from the db again and re-bind to the GridView.
Marked as answer by banksidepoet on Dec 06, 2012 09:57 AM
banksidepoet
Participant
774 Points
862 Posts
Unexpected code execution order causing problems.
Dec 04, 2012 12:30 PM|LINK
Hi,
I have a GridView which contains a ButtonField:
<asp:GridView ID="familyGridView" runat="server" AutoGenerateColumns="False" DataKeyNames="product_id" OnRowCreated="familyGridView_RowCreated" OnRowDataBound="familyGridView_RowDataBound" OnRowCommand="familyGridView_RowCommand"> <Columns> . . <asp:ButtonField ButtonType="Image" Text="Add to Quote" ImageUrl="~/assets/images/buttons/addtocart_small.gif" CommandName="addToQuote"> </asp:ButtonField> </Columns> </asp:GridView>Here are the three event handlers:
protected void familyGridView_RowCreated(Object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { ImageButton addButton = (ImageButton)(e.Row.Cells[5].Controls[0]); addButton.CommandArgument = e.Row.RowIndex.ToString(); TextBox quantityTB = (TextBox)e.Row.FindControl("quantityTextBox"); quantityTB.Text = "0"; quantityTB.Attributes.Add("onfocus", "if(this.value.substr(0, 1) == '0') this.value = '';"); quantityTB.Attributes.Add("onblur", "javascript: if(this.value=='') this.value='0';"); } }The purpose of this handler is simply to place a "0" in quantityTextBox when the page first loads (plus some JS to remove and replce the "0" in response to muse behaviour).
protected void familyGridView_RowDataBound(object sender, GridViewRowEventArgs e) { e.Row.Cells[0].Visible = false; }The purpose of this handler is simply to hide the product_id from view.
// AT EACH "Add To Quote" BUTTON CLICK... protected void familyGridView_RowCommand(object sender, GridViewCommandEventArgs e) { GridViewRow row = ((System.Web.UI.WebControls.GridView)(sender)).Rows[int.Parse(e.CommandArgument.ToString())]; string idString = row.Cells[0].Text; int id = Convert.ToInt32(idString); string codeString = row.Cells[1].Text; int parentid = id - 1; int quantity = Convert.ToInt32(((TextBox)row.FindControl("quantityTextBox")).Text); if (quantity < 1) { Response.Redirect(Request.RawUrl); } . .This handler controls the addition of the product (and its quantity) to the shopping cart.
**********
My problem is that no matter what the user chooses as a quantity in quantityTextBox, this line:
int quantity = Convert.ToInt32(((TextBox)row.FindControl("quantityTextBox")).Text);
always returns "0" and, hence, the if statement that immediately follows this line simply refreshes the page and nothing further happens.
I have debugged the program flow and I know why the value is "0" but I cannot understand why the program flow is like it is.
Here's why. Upon browsing to the page:
Here, I am sent back to the page (from VisualStudio debugger), and I enter a quantity in quantityTextBox fro row 1 and hit that row's button. Then:
By the time the code runs in RowCommand, the value in quantityTextBox is zero, ALWAYS.
How can I avoid the button click running through the RowCreated code?
msmk
Participant
779 Points
166 Posts
Re: Unexpected code execution order causing problems.
Dec 04, 2012 02:38 PM|LINK
When ASP.Net pages postBack, the entire page is recreated. Your rows are therefore recreated and RowCreated will be hit. The data for the gidview should be persisted in the view state and grid should be bound to that data, unless you explicity tell it not to which you do by saying quantityTB.Text = "0";. Try to wrap that code in:
if (!IsPostBack)
{
quantityTB.Text = "0";
}
banksidepoet
Participant
774 Points
862 Posts
Re: Unexpected code execution order causing problems.
Dec 04, 2012 03:01 PM|LINK
msmk,
Thank you for your response.
I understand. I often forget the PostBack: I assumed the button click wouyld just fire RowCommand.
Thanks for the reminder.
banksidepoet
Participant
774 Points
862 Posts
Re: Unexpected code execution order causing problems.
Dec 04, 2012 03:30 PM|LINK
msmk,
Sorry, I thought you'd hit the nail on the head here.
The code actually makes no difference.
Any other ideas?
I have this code working now but the way I got it to work was to take out the C# databinding and use a SqlDataSource instead. The C# is in Page_Load but the quantityTextBox is a stand-alone TemplateField, not a value of 0 pulled from the database so this shouldn't overwrite the user's choice of quantity, should it?
Here's the C#:
SqlDataAdapter sda10 = new SqlDataAdapter(commandString10, conn); sda10.SelectCommand.Parameters.AddWithValue("@active", 'y'); sda10.SelectCommand.Parameters.AddWithValue("@category_id", Request.QueryString["category_id"]); sda10.SelectCommand.Parameters.AddWithValue("@code_from", Request.QueryString["product_id"]); sda10.SelectCommand.Parameters.AddWithValue("@score", 2); sda10.SelectCommand.CommandType = CommandType.Text; DataTable dt10 = new DataTable(); sda10.Fill(dt10); if (dt10.Rows.Count > 0) { familyGridView.DataSource = dt10; familyGridView.DataBind(); familyGridView.Caption = (string)cmd1.ExecuteScalar() + " - Product Family"; dt10.Dispose(); }Ther's obviously a commandString above this.
Just replacing this method of filling the GridView with a SqlDataSource removes the problem all together!?
Any ideas how this would have this effect as I'd rather use the C# method.
Decker Dong ...
All-Star
118619 Points
18779 Posts
Re: Unexpected code execution order causing problems.
Dec 05, 2012 01:40 AM|LINK
Hello,
Just as msmk said——Microsoft only makes to simplify programming of asp.net programming, so it seems that you are developing on WinForm. But in fact, you should know that Html page is of NON-MEMORY, which means it cannot remember what you have given to itself after twice submitting. This just depends on HiddenField (In C# ViewState takes the action).
So you cannot let page remember what you've inputted, and each time you have to (either will be ok).
1) Use js to assign one-by-one textboxes values, even if when the page submitted again and refereshed, it will automatically "remember" things.
2) In the event of RowDataBound, just change the textbox values.
banksidepoet
Participant
774 Points
862 Posts
Re: Unexpected code execution order causing problems.
Dec 05, 2012 05:03 AM|LINK
Decker Dong,
Thank you for the advice: I always prefer to learn than to copy and paste.
Can you, however, explain why the same code works perfectly if I bin the GV to a SqlDataSource in MarkUp but does not work if I bind it to a SqlDataAdapter in CodeBehind (binding posted above)?
I prefer to bind in CodeBehind as I can make the GV NOT SHOW if there is no data to display.
Thanks
Decker Dong ...
All-Star
118619 Points
18779 Posts
Re: Unexpected code execution order causing problems.
Dec 05, 2012 05:34 AM|LINK
Since you are code-behind to bind, please check with Count property——It that's 0, make GridView.Visible=False; otherwises True.
banksidepoet
Participant
774 Points
862 Posts
Re: Unexpected code execution order causing problems.
Dec 05, 2012 06:46 AM|LINK
Sorry, I think you misunderstood my question. I know how to hide the GV.
My question is why the my code to grab the value of the quantity text box works if I bind the GV to a SqlDataSource but not if I bind it to a SqlDataAdapter in C#. I'd really like an answer to this as I prefer to use C# for binding.
Would you like me to post complete code of version that works and version that doesn't?
Decker Dong ...
All-Star
118619 Points
18779 Posts
Re: Unexpected code execution order causing problems.
Dec 06, 2012 12:30 AM|LINK
Hi again,
If you do data-binding yourself, Just like what I say above, Html isn't of NON-Memoryable, which means once you bind data in the Page_Load event, and when you refresh the whole page, the GridView will be re-newed (re-created again). this will make you lose all of your previous data contents. So if you are using SqlDataSource, when you refresh the page, it will fetch all the data contents from the db again and re-bind to the GridView.
banksidepoet
Participant
774 Points
862 Posts
Re: Unexpected code execution order causing problems.
Dec 06, 2012 09:56 AM|LINK
I understand. Thank you for taking the time to explain that.