Hoo boy.
You didn't ask this in your question, but you've written some smelly code here. I'll try to address your question, but I'm also going through some of the other problems here.
Without seeing your markup, it's hard for me to tell if you've created GridViewResult
programmatically or if it's in your markup as well. I'm not exactly sure what TaskGridViewResult
is either -- is this an event for GridViewResult
? Do you have another GridView
on your page, and you want to show GridViewResult
based on some search criteria?
I'm also not sure why you put all of your GridView
binding code in Page_Load
. I see that you're checking GetPostBackControl
to find the control that caused the PostBack
-- this is a code smell. If your users have to click a specific "Search" button, you should isolate your GridView
binding code within that button's Click
event.
Anyway, as to TaskGridViewResult_RowUpdating
:
It looks like you're trying to update GridViewResult
's old values to the new values by setting its DataSource
and then iterating through its data. You can't do that. What happens when you change your RowUpdating
event to:
protected void TaskGridViewResult_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewResult.DataSource = (DataTable)Session["Result"];
GridViewResult.DataBind();
}
Now, other asides:
Your switch
statements are code smells. DropDownList
s expose a property called SelectedValue
-- if you have some default value that isn't a valid selection (like the first option in your DropDownList
), then you can change your original code from:
if ((test.ID == "SumbitSearch") && (DropDownListFrom.Text != "") && (DropDownListTo.Text != "") && (SearchField.Text != ""))
{
string from = string.Empty;
string to = string.Empty;
switch (DropDownListFrom.SelectedIndex)
{
case 0:
from = DropDownListFrom.Items[0].Value;
break;
/* other cases */
}
switch (DropDownListTo.SelectedIndex)
{
case 0:
to = DropDownListTo.Items[0].Value;
break;
/* other cases */
}
/* snip */
}
to:
if (test.ID == "SubmitSearch" && DropDownListFrom.SelectedIndex > 0 && DropDownListTo.SelectedIndex > 0 && SearchField.Text != "")
{
string from = DropDownListFrom.SelectedValue;
string to = DropDownListTo.SelectedValue;
/* snip */
}
If you can, please post your markup. I can offer you some more specific help or advice if I can tell what Controls
you have on your page, and how they interact.
Edit: I should also add that you should get in the habit of using String.IsNullOrEmpty(string variable)
, rather than comparing to ""
. Although this isn't as big of a problem when you're referencing the text from web controls, getting in the habit now will prevent you from serious headaches and inefficiently checking for null and empty later. If you're in .NET 4.0, you should have access to IsNullOrWhiteSpace()
, which is (in my opinion) more useful on the web, where users are more likely to try to enter junk data.
Edit 2: In response to your additional details above:
In your RowUpdating
event, you need to pull the new values out of the front-end controls, and then re-bind your data. It looks like your source code is pretty close to the MSDN source code here. The difference between your code and the code on MSDN is:
- The MSDN code takes the new data from the edited row and updates the appropriate data in the Session
variable with that new data.
- The MSDN code has a BindData()
function -- I'm not sure if this is what your DataBind()
function is, however.
- The MSDN code updates the GridView
by re-binding the GridView
to the appropriate data in the Session
.
Frankly, I have some issues with the MSDN code. I really, really hate seeing code like: dt.Rows[row.DataItemIndex]["Id"] = ((TextBox)(row.Cells[1].Controls[0])).Text;
To me, this is garbage, because it's so highly coupled to the order of your cells.
If I had written the code, I would explicitly create all the front-end controls and use a binding command (if you aren't familiar, it looks like <%# DataBinder.GetPropertyValue(Container.DataItem, "FieldName") %>
in the markup -- see more details here). Then, in my RowUpdating
event, I'd use e.Row.FindControl("controlName")
, and update the Session
data from that.
Honestly, if your back-end data isn't changing on a regular basis, I don't see any reason to programmatically create your GridView
s. It over-complicates your C# code to go through these steps yourself when you can just set it up once in your markup. If you need to hide one GridView
, you can always set its Visible
property to false
. Then, when you're ready to show it, set Visible = true
.
Finally, I've spread my GridView
code across so many events (button clicks, RowDataBound
events from other GridViews
/Repeaters
, etc.), I can't imagine why someone would suggest that you only put it in Page_Load
.
Best Answer
You should use the two way binding here. I.e. Bind instead of Eval:
Here is the link to documentation:
Data-Binding Expressions Overview
Here is my code behind: