I have a gridview showing academy name and a dropdown list. The dropdown list have value of 0-13, 0 is the "Please select option". I want when the save button it skip those row where there is no selection in the dropdown therefore 0.
Here is my code for the gridview:
<asp:GridView ID="gdvAcadSelec" runat="server" AutoGenerateColumns="False"
DataKeyNames="acad_Id"
DataSourceID="srcAcademy"
OnRowDataBound="gdvAcadSelec_RowDataBound"
CssClass="table table-striped table-bordered"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="acad_Id" HeaderText="Id" />
<asp:BoundField DataField="acad_name" HeaderText="Academy" />
<asp:TemplateField HeaderText="Choice">
<ItemTemplate>
<asp:DropDownList ID="ddlPref" OnTextChanged="ddlPref_TextChanged" AutoPostBack="true" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnsubmit" CssClass="btn btn-info" OnClick="btnsubmit_Click" runat="server" Text="Submit" />
<asp:ObjectDataSource ID="srcAcademy"
TypeName="dataAccessLayer"
SelectMethod="getAcademy"
runat="server" />
The code behind for the binding of item for the column Choice:
protected void gdvAcadSelec_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the DropDownList in the Row
DropDownList ddlCountries = (e.Row.FindControl("ddlPref") as DropDownList);
ddlCountries.Items.Insert(0, new ListItem("Please select"));
ddlCountries.Items.Insert(1, new ListItem("1"));
ddlCountries.Items.Insert(2, new ListItem("2"));
ddlCountries.Items.Insert(3, new ListItem("3"));
ddlCountries.Items.Insert(4, new ListItem("4"));
ddlCountries.Items.Insert(5, new ListItem("5"));
ddlCountries.Items.Insert(6, new ListItem("6"));
ddlCountries.Items.Insert(7, new ListItem("7"));
ddlCountries.Items.Insert(8, new ListItem("8"));
ddlCountries.Items.Insert(9, new ListItem("9"));
ddlCountries.Items.Insert(10, new ListItem("10"));
ddlCountries.Items.Insert(11, new ListItem("11"));
ddlCountries.Items.Insert(12, new ListItem("12"));
ddlCountries.Items.Insert(13, new ListItem("13"));
}
On click save button:
protected void btnsubmit_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gdvAcadSelec.Rows)
{
DropDownList ddlorder = (DropDownList)row.FindControl("ddlPref");
string acadID = row.Cells[0].Text;
string order = ddlorder.SelectedValue.ToString();
SqlCommand scmd = new SqlCommand();
scmd.CommandType = CommandType.Text;
scmd.CommandText = "Insert into tblAcademy_Selection (acad_Id,stud_Id,order_preference) values (#acad,#stud,#order)";
scmd.Connection = con;
scmd.Parameters.AddWithValue("#acad", acadID);
scmd.Parameters.AddWithValue("#stud", 60);
scmd.Parameters.AddWithValue("#order", order);
con.Open();
scmd.ExecuteNonQuery();
con.Close();
}
}
The problem with this code is when it is saving to the database ,those dropdowns list who have value "please select" is also being save and this crash my website.
What can I do to skip those dropdown that do not have value selected?
Thank you in advance.
(Edited per request from OP)
Simply use an if() statement to skip the values you don't want to insert.
string order = ddlorder.SelectedIndex.ToString();
if (order != "0") { // Some may argue that it should be !order.equals("0") but in C# it doesn't matter.
SqlCommand scmd = new SqlCommand();
scmd.CommandType = CommandType.Text;
.
.
}
And if you're a prudent (and paranoid) programmer, you won't trust anything sent from the browser, you'll check to make sure the variable order is the appropriate type and is within the range of values you expect as well.
My question is how can i insert values into gridviews rows.Basically I have created a gridview in which i bound the footer and i want to insert values in the footer.I have create a 'textboxs','dropdownlist' and 'checkboxes'.I want when i insert value and press "Insert" button then values shown in the gridview and again i insert value and press button then show inserted values in the gridview.Here is my gridview image
and i also want to edit and delete rows as well.Here is my code :
aspx code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="104px" ShowFooter="True" Width="463px"
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True">
<Columns>
<asp:TemplateField HeaderText="Column Name">
<FooterTemplate>
<asp:TextBox ID="name" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Data Type">
<FooterTemplate>
<asp:DropDownList ID="DropDownList2" runat="server">
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Allow Null">
<FooterTemplate>
<asp:CheckBox ID="allow_null" runat="server" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Primary Key">
<FooterTemplate>
<asp:CheckBox ID="primary" runat="server" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and here is my aspx.cs code :
protected void Button1_Click(object sender, EventArgs e)
{
string name = TextBox1.Text;
string type = DropDownList1.Text;
string allow=Null.Text;
string primary = Primary.Text;
name = ((TextBox)GridView1.FooterRow.FindControl("TextBox2")).Text;
type = ((DropDownList)GridView1.FooterRow.FindControl("DropDownList2")).Text;
allow = ((CheckBox)GridView1.FooterRow.FindControl("allow_null")).Text;
primary = ((CheckBox)GridView1.FooterRow.FindControl("primary")).Text;
}
To use the GridView in this way, with input fields in the footer and a Insert Button that is outside the GridView, you need to make a manual Insert.
I don't know how you perform an Insert using the EF model as I don't currently use it. I guess you could say the "old" way is to use an instance of SqlConnection and SqlCommand. You would use code similar to this inside your Button Click event:
// This is VB. C# is similar, you will have to convert where needed
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand(queryString, connection)
command.Connection.Open()
command.CommandType = // Typically Text or StoredProcedure as needed
command.Parameters.AddWithValue("#parameter_name1", some_value_1)
command.Parameters.AddWithValue("#parameter_name2", some_value_2)
.
.
.
command.ExecuteNonQuery()
End Using
End Using
queryString is your sql INSERT statement or a stored procedure
command.Parameters is a collection of replaceable parameter in your INSERT statement or Stored Proc.
Addendum
A Gridview is a Data bound control so typically when you use a gridview it's bound to some backing data source. If you are not using a database then you are using some other construct.
If you are using, for example, a DataTable, you would add the new rows and columns to the DataTable using its row and column methods and then rebind the DataTable to the Gridview. You don't add rows and columns directly to a GridView.
See this other SO answer by JonH for an example
In case this helps this is based on the ASPSnippets but modified to be more like you might need. Note that instead of using a DataTable I am using a List where "Row" is a class. It is somewhat a matter of personal preference which one you use. The "Row" class is:
[Serializable]
public class Row
{
public string FieldName { get; set; }
public string FieldType { get; set; }
public Boolean FieldNullible { get; set; }
public Boolean FieldPrimaryKey { get; set; }
}
My names are different from your names. Note that the ASPSnippets sample does not use TemplateFields so I am not. I am not sure if you need to make the "allow"
and/or "primary" fields Boolean so I did not process them in the form. So the ASP.Net form I have is:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="104px" Width="463px"
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True">
<Columns>
<asp:BoundField DataField="FieldName" HeaderText="Name" ItemStyle-Width="120" />
<asp:BoundField DataField="FieldType" HeaderText="Type" ItemStyle-Width="120" />
</Columns>
</asp:GridView>
<br /><asp:Label ID="Label1" runat="server" Text="Name:"></asp:Label>
<br /><asp:TextBox ID="txtName" runat="server" />
<br /><asp:Label ID="Label2" runat="server" Text="Type:"></asp:Label>
<br /><asp:TextBox ID="txtType" runat="server" />
<br /><asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="Insert" />
The code-behind is:
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
return;
List<Row> Rows = new List<Row>();
ViewState["Rows"] = Rows;
BindGrid();
}
protected void BindGrid()
{
GridView1.DataSource = (List<Row>)ViewState["Rows"];
GridView1.DataBind();
}
protected void Insert(object sender, EventArgs e)
{
List<Row> Rows = (List < Row >)ViewState["Rows"];
Row r = new Row();
r.FieldName = txtName.Text.Trim();
r.FieldType = txtType.Text.Trim();
Rows.Add(r);
ViewState["Rows"] = Rows;
BindGrid();
txtName.Text = string.Empty;
txtType.Text = string.Empty;
}
One thing I do not like is that the GridView does not show until there is data in it. I assume you can fix that.
This does not implement the editing and deleting.
have a GridView but cannot retrieve any of the data on post-back. I have set a break point at the start of Page_Init and Page_Load, on any post-back that is triggered the GridView.Rows.Count property is always 0. The GridView is defined as shown below:
<asp:GridView ID="TestGrid" runat="server" AllowSorting="False" DataKeyNames="ID,stock,percentage"
OnRowDataBound="GridViewTest_RowDataBound" EnableViewState="True"
OnRowUpdating="GridViewTest_OnRowUpdating" OnRowEditing="GridViewTest_OnRowEditing" OnRowCancelingEdit="GridViewTest_OnRowCancelingEdit"
AutoGenerateColumns="False">
<Columns>
<asp:CommandField ShowEditButton="True" CausesValidation="False"/>
<asp:BoundField DataField="Client" HeaderText="Client" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="Stock" HeaderText="Stock" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="DutyStatus" HeaderText="DutyStatus" InsertVisible="False" ReadOnly="True" />
<asp:TemplateField HeaderText="Percentage" InsertVisible="False">
<ItemTemplate>
<asp:Label ID="enhLbl" runat="server"><%#Eval("Percentage")%></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TbPercentage" runat="server" Text="<%#Bind("Percentage")%>" class="edit-field"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I have a check for IsPostBack in Page_Load and only bind the GridView to its DataSource if it's not a post-back.
The only other time it gets re-bound is in the GridViewTest_OnRowEditing, GridViewTest_OnRowUpdating and GridViewTest_OnRowCancelingEdit event handlers.
I am binding the GridView to a DataTable in the following way:
AGridView.DataSource = DataTableSplitParcels;
AGridView.DataBind();
AGridView.EnableViewState = true;
I don't know if it makes any difference, but the DataTable is created in code and the rows added within a loop.
Within Page_Load on a post-back I can see the GridView has its DataKeysArrayList property populated with the current values, however with it having no rows I am unable to retrieve any updated values.
The problem seems in the Page_Load event, which is refreshing your GridView with every call (irrespective of postback), and because of that you are losing what was entered by the user during update.
So put a debugger on your Page_Load and BindData events and see if it is getting called by Page_Load at all, and you need to stop that.. I tried a sample app and it worked at my end.. see below the code that I tried.
ASPX
<asp:GridView ID="TaskGridView" runat="server"
AutoGenerateEditButton="True"
AllowPaging="true"
OnRowEditing="TaskGridView_RowEditing"
OnRowCancelingEdit="TaskGridView_RowCancelingEdit"
OnRowUpdating="TaskGridView_RowUpdating"
OnPageIndexChanging="TaskGridView_PageIndexChanging">
</asp:GridView>
CS
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Create a new table.
DataTable taskTable = new DataTable("TaskList");
// Create the columns.
taskTable.Columns.Add("Id", typeof(int));
taskTable.Columns.Add("Description", typeof(string));
taskTable.Columns.Add("IsComplete", typeof(bool));
//Add data to the new table.
for (int i = 0; i < 20; i++)
{
DataRow tableRow = taskTable.NewRow();
tableRow["Id"] = i;
tableRow["Description"] = "Task " + i.ToString();
tableRow["IsComplete"] = false;
taskTable.Rows.Add(tableRow);
}
//Persist the table in the Session object.
Session["TaskTable"] = taskTable;
//Bind data to the GridView control.
BindData();
}
}
protected void TaskGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//Retrieve the table from the session object.
DataTable dt = (DataTable)Session["TaskTable"];
//Update the values.
GridViewRow row = TaskGridView.Rows[e.RowIndex];
dt.Rows[row.DataItemIndex]["Id"] = ((TextBox)(row.Cells[1].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["Description"] = ((TextBox)(row.Cells[2].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["IsComplete"] = ((CheckBox)(row.Cells[3].Controls[0])).Checked;
//Reset the edit index.
TaskGridView.EditIndex = -1;
//Bind data to the GridView control.
BindData();
}
private void BindData()
{
TaskGridView.DataSource = Session["TaskTable"];
TaskGridView.DataBind();
}
Source available here
I have a GridView. Whenever I'm clicking on the LinkButton after selecting the Dropdown value, I'm getting only the first item of the Dropdown.
I need to show the selected value in TextBox. How can i get the desired value ?
This is my pseudo code:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" EnableModelValidation="True"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#Eval("ID")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Count">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" EnableViewState="true" AutoPostBack="false">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Button">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">LinkButton</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("Count", typeof(string));
dt.Rows.Add("A", "5");
dt.Rows.Add("B", "8");
dt.Rows.Add("C", "4");
dt.Rows.Add("D", "7");
dt.Rows.Add("E", "9");
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("DropDownList1");
ddl.Items.Clear();
int count = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Count").ToString());
List<string> list = new List<string>();
for (int i = 1; i <= count; i++)
{
list.Add(i.ToString());
}
ddl.DataSource = list;
ddl.DataBind();
}
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
GridViewRow grdrow = (GridViewRow)((LinkButton)sender).NamingContainer;
DropDownList ddl = (DropDownList)GridView1.Rows[grdrow.RowIndex].FindControl("DropDownList1");
TextBox1.Text = ddl.SelectedValue.ToString();
}
Thanks in advance...
I'm going to guess that you should implement INotifyProperty change with the databinding. This way every change will be recorded including those made after first change in the drop down box. see ~ http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
Since you are dynamically creating and binding the Dropdownlist, it would not have loaded at the point your click event is executed. For you to use bound properties (the selectedValue property in this case), the control must already be loaded and it's viewstate info parsed and set by the control.
The databinding event that creates the dropdownlist runs after pre-render. See http://msdn.microsoft.com/en-us/library/ms178472%28v=vs.85%29.aspx for details on the page lifecycle.
To do what you are asking requires very close attention to the page life cycle. Try moving the code that sets the textbox to the GridView1_RowDataBound method. For this to work though, your control must be rendered with the same properties everytime (that way the event's on it are wired up correctly and the selectedValue property is set correctly).
Another alternative is to handle events on the textbox or dropdownlist itself. You would again have to pay attention to the properties and lifecycle of the control.
ASP.Net Forms uses the SmartUI pattern and IMHO this is the single greatest knock against this pattern.
Ok, try this
protected void LinkButton1_Click(object sender, EventArgs e)
{
LinkButton lnkBtn = (LinkButton)sender;
GridViewRow row = (GridViewRow)lnkBtn.NamingContainer;
DropDownList ddl= (DropDownList)row.FindControl("DropDownList1");
TextBox1.Text = ddl.SelectedValue.ToString();
}
This is my .cs code :
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Gridview1.DeleteRow(e.RowIndex);
Gridview1.DataBind();
}
and this is markup,
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false" OnRowDeleting="Gridview1_RowDeleting">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Column Name">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<%-- <asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>--%>
<asp:TemplateField HeaderText="Data Type">
<ItemTemplate>
<asp:DropDownList ID="ddldatatype" runat="server">
<asp:ListItem>varchar</asp:ListItem>
<asp:ListItem>int</asp:ListItem>
<asp:ListItem>numeric</asp:ListItem>
<asp:ListItem>uniqueidentifier</asp:ListItem>
<asp:ListItem>char</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" OnClick="ButtonAdd_Click"/>
<asp:Button ID="ButtonDel" runat="server" Text="Delete Row" OnClick="ButtonDel_Click" />
<input type="hidden" runat="server" value="0" id="hiddencount" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkdelete" runat="server" CommandName="Delete" >Delete</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
Please sugegest me. I have done this much.. but still not deleting row...
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//Gridview1.DeleteRow((int)Gridview1.DataKeys[e.RowIndex].Value);
//Gridview1.DeleteRow(e.RowIndex);
//Gridview1.DataBind();
foreach(DataRow dr in dt.Rows)
{
dt.Rows.Remove(dr);
dt.Rows[e.RowIndex].Delete();
}
Gridview1.DeleteRow(e.RowIndex);
// dt = (DataTable)Gridview1.DataSource;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
GridViewRow row = (GridViewRow)GridView1.Rows[e.RowIndex];
SqlCommand cmd = new SqlCommand("Delete From userTable (userName,age,birthPLace)");
GridView1.DataBind();
}
Make sure to create a static DataTable object and then use the following code:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
dt.Rows.RemoveAt(e.RowIndex);
GridView1.DataSource = dt;
GridView1.DataBind();
}
Try This Make sure You mention Datakeyname which is nothing but the column name (id) in your designer file
//your aspx code
<asp:GridView ID="dgUsers" runat="server" AutoGenerateSelectButton="True" OnDataBound="dgUsers_DataBound" OnRowDataBound="dgUsers_RowDataBound" OnSelectedIndexChanged="dgUsers_SelectedIndexChanged" AutoGenerateDeleteButton="True" OnRowDeleting="dgUsers_RowDeleting" DataKeyNames="id" OnRowCommand="dgUsers_RowCommand"></asp:GridView>
//Your aspx.cs Code
protected void dgUsers_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int id = Convert.ToInt32(dgUsers.DataKeys[e.RowIndex].Value);
string query = "delete from users where id= '" + id + "'";
//your remaining delete code
}
Your delete code looks like this
Gridview1.DeleteRow(e.RowIndex);
Gridview1.DataBind();
When you call Gridview1.DataBind() you will populate your gridview with the current datasource. So, it will delete all the existent rows, and it will add all the rows from CustomersSqlDataSource.
What you need to do is delete the row from the table that CustomersSqlDataSource querying.
You can do this very easy by setting a delete command to CustomersSqlDataSource, add a delete parameter, and then execute the delete command.
CustomersSqlDataSource.DeleteCommand = "DELETE FROM Customer Where CustomerID=#CustomerID"; // Customer is the name of the table where you take your data from. Maybe you named it different
CustomersSqlDataSource.DeleteParameters.Add("CustomerID", Gridview1.DataKeys[e.RowIndex].Values["CustomerID"].ToString());
CustomersSqlDataSource.Delete();
Gridview1.DataBind();
But take into account that this will delete the data from the database.
The easiest way is to create your GridView with some data source in ASP and call that data source in Row_Deletinng Event. For example if you have SqlDataSource1 as your GridView data source, your Row_Deleting event would be:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int ID = int.Parse(GridView1.Rows[e.RowIndex].FindControl("ID").toString());
string delete_command = "DELETE FROM your_table WHERE ID = " + ID;
SqlDataSource1.DeleteCommand = delete_command;
}
See the following code and make some changes to get the answer for your question
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void CustomersGridView_RowDeleting
(Object sender, GridViewDeleteEventArgs e)
{
TableCell cell = CustomersGridView.Rows[e.RowIndex].Cells[2];
if (cell.Text == "Beaver")
{
e.Cancel = true;
Message.Text = "You cannot delete customer Beaver.";
}
else
{
Message.Text = "";
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>GridView RowDeleting Example</title>
</head>
<body>
<form id="form1" runat="server">
<h3>
GridView RowDeleting Example
</h3>
<asp:Label ID="Message" ForeColor="Red" runat="server" />
<br />
<asp:GridView ID="CustomersGridView" runat="server"
DataSourceID="CustomersSqlDataSource"
AutoGenerateColumns="False"
AutoGenerateDeleteButton="True"
OnRowDeleting="CustomersGridView_RowDeleting"
DataKeyNames="CustomerID,AddressID">
<Columns>
<asp:BoundField DataField="FirstName"
HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="StateProvince" HeaderText="State"
SortExpression="StateProvince" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="CustomersSqlDataSource" runat="server"
SelectCommand="SELECT SalesLT.CustomerAddress.CustomerID,
SalesLT.CustomerAddress.AddressID,
SalesLT.Customer.FirstName,
SalesLT.Customer.LastName,
SalesLT.Address.City,
SalesLT.Address.StateProvince
FROM SalesLT.Customer
INNER JOIN SalesLT.CustomerAddress
ON SalesLT.Customer.CustomerID =
SalesLT.CustomerAddress.CustomerID
INNER JOIN SalesLT.Address ON SalesLT.CustomerAddress.AddressID =
SalesLT.Address.AddressID"
DeleteCommand="Delete from SalesLT.CustomerAddress where CustomerID =
#CustomerID and AddressID = #AddressID"
ConnectionString="<%$ ConnectionStrings:AdventureWorksLTConnectionString %>">
<DeleteParameters>
<asp:Parameter Name="AddressID" />
<asp:Parameter Name="CustomerID" />
</DeleteParameters>
</asp:SqlDataSource>
</form>
</body>
</html>
In Grid use this code having ID as your Primary Element so to uniquely identify each ROW
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="Hf_ID" runat="server" Value='<%# Eval("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
and to search the uique ID use the code in C# code behind (basically this is searching hidden field and storing it in a var)
protected void Grd_Registration_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
var ID = (HiddenField)Grd_Registration.Rows[e.RowIndex].FindControl("ID");
//Your Delete Logic Goes here having ID to delete
GridBind();
}
The solution is somewhat simple; once you have deleted the row from the datagrid (Your code ONLY removes the row from the grid and NOT the datasource) then you do not need to do anything else.
As you are doing a databind operation immediately after, without updating the datasource, you are re-adding all the rows from the source to the gridview control (including the row removed from the grid in the previous statement).
To simply delete from the grid without a datasource then just call the delete operation on the grid and that is all you need to do... no databinding is needed after that.
Add the below line in Page load,
ViewState["GetRecords"] = dt;
then try this,
protected void DeleteRows(object sender, GridViewDeleteEventArgs e)
{
dt = ViewState["GetRecords"] as DataTable;
dt.Rows.RemoveAt(e.RowIndex);
dt.AcceptChanges();
ViewState["GetRecords"] = dt;
BindData();
}
If you Still have any problem, send the code in BindData() method
I think you are doing same mistake of rebinding as mentioned in this link
How to delete row from gridview?
If I remember from your previous questions, you're binding to a DataTable. Try this:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
DataTable sourceData = (DataTable)GridView1.DataSource;
sourceData.Rows[e.RowIndex].Delete();
GridVie1.DataSource = sourceData;
GridView1.DataBind();
}
Essentially, as I said in my comment, grab a copy of the GridView's DataSource, remove the row from it, then set the DataSource to the updated object and call DataBind() on it again.
Here is a trick with what you want to achieve. I was also having problem like you.
Its hard to get selected row and data key in RowDeleting Event But it is very easy to get selected row and datakeys in SelectedIndexChanged event. Here's an example-
protected void gv_SelectedIndexChanged(object sender, EventArgs e)
{
int index = gv.SelectedIndex;
int vehicleId = Convert.ToInt32(gv.DataKeys[index].Value);
SqlConnection con = new SqlConnection("-----");
SqlCommand com = new SqlCommand("DELETE FROM tbl WHERE vId = #vId", con);
com.Parameters.AddWithValue("#vId", vehicleId);
con.Open();
com.ExecuteNonQuery();
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = GridView1.SelectedIndex;
int id = Convert.ToInt32(GridView1.DataKeys[index].Value);
SqlConnection con = new SqlConnection(str);
SqlCommand com = new SqlCommand("spDelete", con);
com.Parameters.AddWithValue("#PatientId", id);
con.Open();
com.ExecuteNonQuery();
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
I know this is a late answer but still it would help someone in need of a solution.
I recommend to use OnRowCommand for delete operation along with DataKeyNames, keep OnRowDeleting function to avoid exception.
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false" OnRowDeleting="Gridview1_RowDeleting" OnRowCommand="Gridview1_RowCommand" DataKeyNames="ID">
Include DataKeyNames="ID" in the gridView and specify the same in link button.
<asp:LinkButton ID="lnkdelete" runat="server" CommandName="Delete" CommandArgument='<%#Eval("ID")%>'>Delete</asp:LinkButton>
protected void Gridview1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
int ID = Convert.ToInt32(e.CommandArgument);
//now perform the delete operation using ID value
}
}
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//Leave it blank
}
If this is helpful, give me +
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
MySqlCommand cmd;
string id1 = GridView1.DataKeys[e.RowIndex].Value.ToString();
con.Open();
cmd = new MySqlCommand("delete from tableName where refno='" + id1 + "'", con);
cmd.ExecuteNonQuery();
con.Close();
BindView();
}
private void BindView()
{
GridView1.DataSource = ms.dTable("select * from table_name");
GridView1.DataBind();
}
//message box before deletion
protected void grdEmployee_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (DataControlFieldCell cell in e.Row.Cells)
{
foreach (Control control in cell.Controls)
{
LinkButton button = control as LinkButton;
if (button != null && button.CommandName == "Delete")
button.OnClientClick = "if (!confirm('Are you sure " +
"you want to delete this record?')) return false;";
}
}
}
}
//deletion
protected void grdEmployee_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
conn.Open();
int empid = Convert.ToInt32(((Label)grdEmployee.Rows[e.RowIndex].Cells[0].FindControl("lblIdBind")).Text);
SqlCommand cmdDelete = new SqlCommand("Delete from employee_details where id=" + empid, conn);
cmdDelete.ExecuteNonQuery();
conn.Close();
grdEmployee_refreshdata();
}