I had posted a thread a while back about avoiding adding blank rows into the database. Before when something was to click add row it would automatically add a blank row into the database regardless if the user canceled the new row. I figured it out but now came to a new issue. If the user decides to reload the page(F5) while editing the new row, it will add a blank row into the database, thats a no no for my situation. Can anyone help me figure out how to avoid that?
Below is my insert code:
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert") //- this is needed to explain that the INSERT command will only work when INSERT is clicked
{
gv.DataBind();
DataTable d = dbcon.GetDataTable("SELECT * FROM CIS.CIS_TRANS ORDER BY ID DESC", "ProjectCISConnectionString");
string transCode = "", fundCode = "", BSA_CD = "", DP_TYPE = "";
if (d.Rows.Count > 0)
{
transCode = d.Rows[0]["TRANS_CD"].ToString();
fundCode = d.Rows[0]["FUND_CD"].ToString();
BSA_CD = d.Rows[0]["BSA_CD"].ToString();
DP_TYPE = d.Rows[0]["DP_TYPE"].ToString();
if (transCode.Trim().Length > 0)
{
dbcon.Execute("INSERT INTO CIS.CIS_TRANS (ID,TRANS_CD) VALUES(CIS.S_CIS_TRANS.nextval,'')", "ProjectCISConnectionString");
gv.DataBind();
}
}
gv.EditIndex = gv.Rows.Count - 1;
}
else if (e.CommandName == "Cancel")
{
DataTable d = dbcon.GetDataTable("SELECT * FROM CIS.CIS_TRANS ORDER BY ID DESC", "ProjectCISConnectionString");
string transCode = "";
if (d.Rows.Count > 0)
{
transCode = d.Rows[0]["TRANS_CD"].ToString();
if (transCode.Trim().Length == 0)
{
dbcon.Execute(string.Format("DELETE CIS.CIS_TRANS WHERE ID = '{0}'", d.Rows[0]["ID"]), "ProjectCISConnectionString");
gv.DataBind();
}
}
}
}
If you want to avoid inserting blank row by the user, you need validators. Add RequiredFieldValidator to the insert template:
<asp:RequiredFieldValidator runat="server" ID="valFieldName"
< ControlToValidate="txtFieldName" ErrorMessage="FieldName is missing" />
In your method check if Page.IsValid == true before you insert to the database.
EDIT:
If you want to avoid postbacks completely, you can insert the whole grid into an UpdatePanel:
<asp:UpdatePanel>
<ContentTemplate>
<asp:GrdiView>
....
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Now when the user hits F5 he just reload the page again and not posting back an insert command.
It seems like you try to bring too much logic into one part of code. You put data base logic into button commands. Imagine the user just spams this button. That'd cause huge amounts of empty rows.
Try this approach: divide your database logic and your UI logic (e.g. MVVM). That's a common pattern, today.
Imagine you created all your objects and now the user hits the "save" button (that might also happen through changing a row - whatever). After the save command is executed your view model (the logic behind the view) could e.g. validate your data. So you could expand the functionality on your UI much easier (as said: validation or similar stuff).
If you'd like to do this with your current code, every expansion would blow it up more and more - and it doesn't take too much time till maintaining this code is horrendous.
After everything in your VM happend (validation etc.) the transaction command into your DB could happen (something like myEntities.Save()). And this method provides that your business objects get correctly transformed into SQL and stored in your database.
That was just a very brief explanation of the MVVM pattern, but that seems like the only proper solution here to me.
Related
I have a drop down list with the list items created in the code behind. ddlFill(). Pretty simple and does the job. It's populated with the current month and some months ahead. I use this drop down as a selection to fill a Gridview. When this drop down index changes, it changes a hidden field value and a corresponding query to fill the gridview. All this works as it should. Within the gridview I have another dropdown list and a button. Both submit the selected row to a database. That also works fine. The problem is, each time one of these rows submits to the database, it causes a post back and it resets the whole page. It resets the drop down list to the first list item . I.E. I change the drop down list to index 4 for example. Which would be April in this case. If I submit a row to the db, the page refreshes and goes back to index 0 .. January in this case. How do I keep it from resetting this way and maintaining the position I was in when I submitted the row?
I have tried a few different options. I've tried session states. hidden field value changes. Nothing seems to work. It either does not perform the post back therefore never submits to the db or it does the post back, submits correctly, then resets the whole page. Including resetting the hiddenfield value back to 0
/* This is up in Page load. */
if (Session["pageStatus"] != null)
{
if (Session["pageStatus"].ToString() == "Loaded")
{
hf2.Value = "Loaded";
}
}
else
{
hf2.Value = "New";
}
if (Session["selectedMonth"] != null)
{
hf1.Value = Session["selectedMonth"].ToString();
}
if (ViewState["button_was_clicked"] != null)
{
ddlFill();
StyleDDL();
}
lblTestlabel.Text = hf2.Value;
AddAttributes();
ShowMonth();
if (!Page.IsPostBack)
{
btnReviewCurrentMonth_OnClick(sender, e);
ddlFill();
StyleDDL();
}
private void ddlFill()
{
string a, b, c, d, e, f;
a = "0";
b = "1";
c = "2";
d = "3";
e = "4";
f = "5";
DropDownList1.Items.Insert(0, new ListItem(ReturnMonth(a))); // A blank object call and the ReturnMonth Method fill the list items.
DropDownList1.Items.Insert(1, new ListItem(ReturnMonth(b)));
DropDownList1.Items.Insert(2, new ListItem(ReturnMonth(c)));
DropDownList1.Items.Insert(3, new ListItem(ReturnMonth(d)));
DropDownList1.Items.Insert(4, new ListItem(ReturnMonth(e)));
DropDownList1.Items.Insert(5, new ListItem(ReturnMonth(f)));
/* These were for various testing options to get it to maintain the
state */
hf2.Value = "Loaded";
Session["pageStatus"] = "Loaded";
DropDownList1.SelectedIndex = Int32.Parse(hf1.Value);
}
My goal is to maintain the state of the page after the submission to the db occurs.
I found this question difficult to ask because it had so many moving parts. The ddlFill() method wasn't the problem. All it litterally did was fill list items. Those corresponding Selected Index values would change when selected and based on those values I would assign a different value to a hidden field. Which was then used as SqlDataSource control variable and would bring back GridView data based on that control value.
A drop down list within the gridview was used to select and submit the indexed row to a SQL DB. At the end of that code I was refreshing the page. It needed a refresh to properly submit and bring back a fresh Gridview with the previously submitted row now gone. That was the problem. When it refreshed, it changed the hidden field value to 0 and reset everything back. So, here is what I did.
//This method controls the Drop Down List change event. Underwriter change.
protected void DropDownList1_OnSelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
GridViewRow row = (GridViewRow)ddl.Parent.Parent;
int idx = row.RowIndex;
GridView1.SelectedIndex = idx;
string Client = GridView1.SelectedRow.Cells[0].Text;//Client Name
string NewUw = ddl.Text.ToString();
int UniqCNT = new Int32();
UniqCNT = Int32.Parse(GridView1.SelectedRow.Cells[1].Text.ToString()); //UniqClient */
string ExpPolicyNums = GridView1.SelectedRow.Cells[2].Text;
int Ub = Int32.Parse(GridView1.SelectedRow.Cells[10].Text);//UniqBroker
DateTime ExperationDate = DateTime.Parse(GridView1.SelectedRow.Cells[6].Text); //ExpDate
string Company = GridView1.SelectedRow.Cells[7].Text; //Company issuer
string Broker = GridView1.SelectedRow.Cells[8].Text; //Broker_Name
string Premium = GridView1.SelectedRow.Cells[3].Text; //Premiums
string TotalPremium = GridView1.SelectedRow.Cells[4].Text; //Total premiums
string Reviewed = "No"; //Updates the DB and shows that it hasn't been reviewed by the Message Creator
//DateCreated gets inserted when record is created
string InsertedBy = Request.LogonUserIdentity.Name.Substring(Request.LogonUserIdentity.Name.LastIndexOf(#"\") + 1);
DateTime dateUpDated = DateTime.Now; //Inserts a dateUpdated record
string query = "INSERT INTO [GTU_Apps].[dbo].[Reviewed_Renewal_Policy] (UniqClient, Client, [Expiring_Policies], Premiums, TotalPremium, UniqBroker, ExpDate, NewUw, Company, Broker_Name, Reviewed, DateUpDated, InsertedBy) " +
"VALUES (#UniqCNT, #Client, #ExpPolicyNums, #Premium, #TotalPremium, #Ub, #ExperationDate, #NewUw, #Company, #Broker, #Reviewed, #dateUpDated, #InsertedBy)";
using (SqlConnection conn = new SqlConnection("Data Source=GTU-BDE01;Initial Catalog=GTU_Apps;Integrated Security=True"))
{
using (SqlCommand comm = new SqlCommand(query, conn))
{
comm.Parameters.AddWithValue("#UniqCNT", UniqCNT);
comm.Parameters.AddWithValue("#Client", Client);
comm.Parameters.AddWithValue("#ExpPolicyNums", ExpPolicyNums);
comm.Parameters.AddWithValue("#Premium", Premium);
comm.Parameters.AddWithValue("#TotalPremium", TotalPremium);
comm.Parameters.AddWithValue("#Ub", Ub);
comm.Parameters.AddWithValue("#ExperationDate", ExperationDate);
comm.Parameters.AddWithValue("#NewUw", NewUw);
comm.Parameters.AddWithValue("#Company", Company);
comm.Parameters.AddWithValue("#Broker", Broker);
comm.Parameters.AddWithValue("#Reviewed", Reviewed);
comm.Parameters.AddWithValue("#dateUpDated", dateUpDated);
comm.Parameters.AddWithValue("#InsertedBy", InsertedBy);
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
}
}
GridView1.DataBind();
GridView1.SelectedIndex = -1;
int index = DropDownList1.SelectedIndex;
ConfirmIndex(index);
//End(sender, e);
}
Using the DataBind worked. It only refreshed the Gridview. Which was really what I needed. I had other items that were refreshing too. That's why those calls below it are there. If someone sees this, hopefully it will help.
I am using EntityFramework 4 to manage my data in a simple grid. It is something we needed to just keep track of a checkbox in a table. It was intended to be a quick fix to get data in/out from a little table, not a big project.
I have the following defined in my form
private MyDBEntites _context = new MyDBEntities(...);
private BindingSource myBindingSource = new BindingSource(...);
public DataGridView myGrid = new DataGridView();
In my constructor, I populate the grid
int customerID = 1234;
myGrid.DataSource = myBindingSource;
myBindingSource.DataSource = (from cc In _context.myRecords
where cc.CustomerID = customerID
select cc).AsEnumerable();
My intent is to then modify the table as-needed. When I'm finished making changes, I click a button that calls SaveForm()
public void SaveForm()
{
_context.SaveChanges();
}
For adding and modifying rows, this works very well. However, when I delete a row, then call SaveChanges, above, my application crashes with "The object is in a detached or deleted state". This is even true when I've done absolutely nothing except delete a row.
Why can't I delete a row in this way? Does anyone know what might be getting "changed" before deletion? If so, do you know how I can work around this?
UPDATE
I still don't know WHY it is failing, but I do have a work-around. I was trying to queue-up the deletes and manage all of my changes with one "SaveChanges()" call. There was no business need for this. Just a personal preference. Instead, I've put a SaveChanges at the end of the Remove, and that is working perfectly.
private void myGrid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
if (e.Row == null)
{
return;
}
if ((MessageBox.Show("Are you certain that you want to delete this entry?", "", MessageBoxButtons.YesNo) == DialogResult.Yes))
{
myRecord req = (myRecord)e.Row.DataBoundItem;
myBindingSource.Remove(req);
_context.myRecords.DeleteObject(req);
_context.SaveChanges();
}
}
My web form starts out as two TextBoxes, two Buttons, a CheckBoxList (bound to the results of a database query), and an empty DropDownList.
When the user enters a search phrase into the first TextBox and hits enter (or clicks the first Button, "Search"), a GridView appears, populated with rows pulled from the database. When the user hits the Select button on one of the rows, the DropDownList is populated (bound to results of a database query) and enabled (if the query returned results -- if there were no results, it remains disabled). When the second Button ("Save Settings") is clicked, the relevant data is saved to the DB, the GridView's selection is cleared, and the DropDownList is cleared and disabled.
All of the above works. The problem comes from the DropDownList. I can't get the C# code to recognize the changing SelectedIndex; depending on how I shuffle my code around, the index is always either 0 (and the DropDownList is forced to stay on the first item), or -1 (and the list becomes disabled).
DropDownList code:
<asp:DropDownList ID="myList" runat="server" AutoPostBack="True"
DataTextField="MyName" DataValueField="MyID"
Enabled="False" onselectedindexchanged="myList_SelectedIndexChanged" />
C# code:
protected void myGrid_SelectedIndexChanged(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
if (myGrid.SelectedIndex >= 0)
{
int id = int.Parse(myGrid.Rows[myGrid.SelectedIndex].Cells[2].Text);
connection.Open();
string query = "..."; // Omitted for brevity; the query is correct
SqlDataSource source = new SqlDataSource(connectionString, query);
source.SelectParameters.Add("Param1", TypeCode.String, id.ToString());
DataTable dt = ((DataView)source.Select(DataSourceSelectArguments.Empty)).Table;
dt.AcceptChanges();
myList.DataSource = dt;
myList.DataBind();
myList.Enabled = myList.Items.Count != 0;
if (!myList.Enabled)
{
myList.Items.Add(new ListItem("No Results", "0"));
}
}
}
}
protected void myList_SelectedIndexChanged(object sender, EventArgs e)
{
// ((DropDownList)sender).SelectedIndex == -1
}
I've read that there are some problems with DropDownList while searching for a solution to my problem, but besides the note to set AutoPostBack="True", none of the other situations I've found have helped.
One common reason on why the DropDownList loses its SelectedIndex value is, that during the postback is binded again with data. Do you populate data to the DropDownList somewhere else in your code? Maybe there is something else that causes the SelectedIndex event of the GridView to fire again?
Another thought is that changing the Enabled status of the DropDownList might cause this behavior. Try your code without disabling the DropDownList, and see if something changes.
I have at the moment a problem with RowUpdating from a GridView and accessing the new values. I add a dynamic DataTable to my GridView.DataSource and bind to it. If I use the update button nothing happens and I get back to my normal GridView.
Here's my Page_Load event:
protected void Page_Load(object sender, EventArgs e)
{
Control test = GetPostBackControl(Page);
if (Page.IsPostBack)
{
if ((test.ID == "SumbitSearch") && (DropDownListFrom.Text != "") && (DropDownListTo.Text != "") && (SearchField.Text != ""))
{
DataTable result = new DataTable();
string from = null;
string to = null;
switch (DropDownListFrom.SelectedIndex)
{
case 0:
from = DropDownListFrom.Items[0].Value;
break;
case 1:
from = DropDownListFrom.Items[1].Value;
break;
case 2:
from = DropDownListFrom.Items[2].Value;
break;
}
switch (DropDownListTo.SelectedIndex)
{
case 0:
to = DropDownListTo.Items[0].Value;
break;
case 1:
to = DropDownListTo.Items[1].Value;
break;
case 2:
to = DropDownListTo.Items[2].Value;
break;
}
result = LoadGridView(from, to);
GridViewResult.DataSource = result;
Session["Result"] = result;
GridViewResult.DataBind();
GridViewResult.Columns[0].Visible = true;
GridViewResult.Columns[1].Visible = true;
GridViewResult.HeaderRow.Cells[0].Width = Unit.Pixel(110);
GridViewResult.HeaderRow.Cells[1].Width = Unit.Pixel(60);
GridViewResult.HeaderRow.Cells[3].Text = "Nach: " + from;
GridViewResult.HeaderRow.Cells[4].Text = "Von: " + to;
}
}
else
{
GridViewResult.DataBind();
}
}
Later, the GridView should only appear if both DropDownLists are used and the SearchField is not empty. I also check if the button which execute the PostBack is the search button.
Here is what I added to the RowUpdating EventHandler:
protected void TaskGridViewResult_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewResult.DataSource = (DataTable)Session["Result"];
for (int i = 0; i < GridViewResult.Columns.Count; i++)
{
DataControlFieldCell cell = GridViewResult.Rows[e.RowIndex].Cells[i] as DataControlFieldCell;
GridViewResult.Columns[i].ExtractValuesFromCell(e.NewValues, cell, DataControlRowState.Edit, true);
}
GridViewResult.EditIndex = -1;
DataBind();
}
What is going wrong?
Last Change: More Information (#jwiscarson)
I’m sorry, I was in hurry. I will try to give you a better view.
In that project, the users could select 2 categories, enter a search string and the result will show in a GridView. The RowUpdating stuff is for the "admin user".
Here is my problem, if the "admin user" click on edit, change the value of the cell and execute the update, the value would not changed in the DataTable.
Without seeing your markup, it's hard for […] based on some search
criteria?
I add GridViewResult as markup in my project.
I'm also not sure why […] within that button's Click event.
Yes, I thought that too! But I read in a blog it is better to put the code into Page_Load(), if you are working with GridViews. I believed him. Is it okay, to put that code into the click event handler from my button? I'm very new to that. I just could read lots of blogs, msdn and ask here.
TaskGridViewResult_RowUpdating is also added as markup to my code. Could I also create this and the GridView in my CreateChildControls()?
As markups I have two DropDownLists, a TextBox for the search string, a search submit Button and the GridView.
At the moment, i havent the exactly code here but the GridView looks like:
<asp:GridView ID="GridView1" runat="server"
OnRowUpdating="TaskGridViewResult_RowUpdating">
<!-- // More of that... -->
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>
I could give you more details tomorrow.
Maybe I forgot this. Before I could click the update button and execute the TaskGridViewResult_RowUpdating event to change the value of the cell. I set the row editable with:
protected void TaskGridViewResult _RowEditing(object sender, GridViewEditEventArgs e)
{
GridViewResult.EditIndex = e.NewEditIndex;
DataBind();
}
Next Change:
I added to the GridView few TemplateFields like:
<asp:TemplateField HeaderText="test">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("from") %>'> </asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("from") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
This is it, I have access to the new value with:
string test = ((TextBox)row.FindControl("TextBox1")).Text;
in TaskGridViewResult_RowUpdating()
Now, I just have to bind the template dynamically with the values from the dropdown list, and that’s it I think.
Thanks!
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. DropDownLists 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 GridViews. 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.
I've got a gridview displaying product instance info; I need a hyperlink in my Action column to bring up an view/edit page that displays the row data. How do I make the link bring up the data from that specific row into the edit page?
Note: there are other questions with similar titles, however, they do not cover this specific topic.
Use datakeys in the gridview, using datakey will get you the id of each clicked hyperlink , and then you can use that id to edit or delete the selected items easily. In the code behind just find the hyperlink control , pass the data key and write d update sql for it. Inorder to move your data to other pages you can sessions but if you are developing a commercial website session wont be a good idea due to its security issues, use cookies in that case .
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["productID"] != null)
{
productID = Convert.ToInt32(Request.QueryString["productID"]);
bindData(productID)
}
...
}
}
protected void bindData(int productID)
{
//to avoid sql injection as mentioned below use parameters
SqlConnection conn = new SqlConnection(ConnectionString); // define connection string globally or in your business logic
conn.Open();
SqlCommand sql = new SqlCommand("Select * From [Table] Where ID = #productID",conn);
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#ID";
parameter.Value = productID;
sql.Parameters.Add(parameter);
conn.close()
}
You can also use Microsoft.ApplicationBlocks.Data.dll to avoid repeating ado.net , it will reduce your code.
Try something like this?
ViewProducts.aspx:
<columns>
<asp:HyperLinkField DataNavigateUrlFields="ProductID" HeaderText="Edit"
ItemStyle-Width="80"
DataNavigateUrlFormatString="EditProduct.aspx?productID={0}"
Text="Select" ItemStyle-HorizontalAlign="Center" />
...
</columns>
EditProduct.aspx:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["productID"] != null)
{
productID = Convert.ToInt32(Request.QueryString["productID"]);
...
}
...
}
}
There are n+1 ways to solve this problem. If you are using the sql data source you can accentually have VS generate the sql and edit logic for you if you don't have specific requirements. here is a code project tutorial.
Another oft used tactic is to add a command button to the row and populate the command argument with the ID of the row you want to edit then in the oncommand event handle what ever logic you need.
you can also use a simple html link and and use get parameters. Or you can session like I said there a a ton of ways to solve this problem.