I am working with .NET Webforms in C#, and right now I am trying to add and subtract a row in a gridview on a button click. I've got an add, and remove button in the footer template, and I have the add button working alright, but removing the last row, while retaining any data that may have been entered in the others is where I am having the issue. Basically I can remove the last row, but I fill out multiple rows of data before hand, it's all erased when I remove the last row. I want to retain all the data entered, and just subtract the last row index from the gridview. here is my gridview:
<!-- ADD COURSE GRIDVIEW -->
<asp:GridView ID="Course_Gridview" runat="server" ShowFooter="True" AutoGenerateColumns="false" class="table table-striped" GridLines="None" Visible="false">
<Columns>
<asp:BoundField DataField="RowNumberCourse" HeaderText="Course #" />
<asp:TemplateField HeaderText="Course">
<ItemTemplate>
<asp:DropDownList ID="CourseList" runat="server" DataSourceID="CourseListODS" DataTextField="SubjectName"
DataValueField="CourseID" AppendDataBoundItems="true" CssClass="form-control course-ddl-fix">
<asp:ListItem Value="0">---------[Select]---------</asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server"
ErrorMessage="Please select a Program Length value from the list." Display="Dynamic" ControlToValidate="CourseList"
InitialValue="0" Text="*" CssClass="require-fix"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Mark">
<ItemTemplate>
<asp:TextBox ID="EnterMark" runat="server" CssClass="form-control pgm-length-fix"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" runat="server"
ErrorMessage="Please enter a Mark when inserting a course." Text="*" ControlToValidate="EnterMark"
Display="Dynamic" CssClass="require-fix"></asp:RequiredFieldValidator>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add Another Course..." OnClick="ButtonAdd_Click" CssClass="listview-buttons" CausesValidation="False"/>
<asp:LinkButton ID="ButtonSubtract" runat="server" CssClass="btn btn-default btn-sm delete-fix"
OnClick="ButtonSubtract_Click" CausesValidation="false">
<i aria-hidden="true" class="glyphicon glyphicon-remove"></i> Remove...</asp:LinkButton>
</FooterTemplate>
</asp:TemplateField>
</Columns>
And here is the method for subtracting the last row:
protected void ButtonSubtract_Click(object sender, EventArgs e)
{
if (ViewState["CurrentTableCourse"] != null)
{
//create new datatable, cast datatable of viewstate
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTableCourse"];
DataRow drCurrentRow = null;
int rowIndex = 0;
if (dtCurrentTable.Rows.Count > 1)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the values
DropDownList courseList = (DropDownList)Course_Gridview.Rows[rowIndex].Cells[1].FindControl("CourseList");
TextBox marks = (TextBox)Course_Gridview.Rows[rowIndex].Cells[2].FindControl("EnterMark");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumberCourse"] = i;
dtCurrentTable.Rows[i - 1]["Column1Course"] = courseList.Text;
dtCurrentTable.Rows[i - 1]["Column2Course"] = marks.Text;
rowIndex++;
}
dtCurrentTable.Rows[rowIndex - 1].Delete();
ViewState["CurrentTableCourse"] = dtCurrentTable;
Course_Gridview.DataSource = dtCurrentTable;
Course_Gridview.DataBind();
}
}
}
How would I go about keeping all the values entered, aside from the last one which is removed?
thanks for the reply, but I just got it. I needed to add the following methods for it to work accordingly:
private void SetPreviousCourseData()
{
int rowIndex = 0;
if (ViewState["CurrentTableCourse"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTableCourse"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
DropDownList courseList = (DropDownList)Course_Gridview.Rows[rowIndex].Cells[1].FindControl("CourseList");
TextBox marks = (TextBox)Course_Gridview.Rows[rowIndex].Cells[2].FindControl("EnterMark");
courseList.Text = dt.Rows[i]["Column1Course"].ToString();
marks.Text = dt.Rows[i]["Column2Course"].ToString();
rowIndex++;
}
}
}
}
Call this method if(!Page.IsPostBack):
private void SetInitialCourse()
{
//Create DataTable
DataTable dt = new DataTable();
DataRow dr = null;
//Add initail values to DataTable
dt.Columns.Add(new DataColumn("RowNumberCourse", typeof(string)));
dt.Columns.Add(new DataColumn("Column1Course", typeof(string)));
dt.Columns.Add(new DataColumn("Column2Course", typeof(string)));
//dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumberCourse"] = 1;
dr["Column1Course"] = string.Empty;
dr["Column2Course"] = string.Empty;
//dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
dr = dt.NewRow();
//Store the DataTable in ViewState
ViewState["CurrentTableCourse"] = dt;
Course_Gridview.DataSource = dt;
Course_Gridview.DataBind();
}
Related
How to Add Dynamic Text Box inside child gridview
?Below screen shot will give clear picture of my question.I am unable to add on second row which is shown in screen shot.
Screen shot
Thank you in advance
Adding Dynamic Rows in GridView with TextBoxes
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<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="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
Your Binding Code
private void SetInitialRow(){
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
//Store the DataTable in ViewState
ViewState["CurrentTable"] = dt;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
Page Load Event Code
if (!Page.IsPostBack){
SetInitialRow();
}
Running the codes above will give us this output below:
method for generating the rows when clicking the Button
private void AddNewRowToGrid(){
int rowIndex =0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
drCurrentRow["Column1"] = box1.Text;
drCurrentRow["Column2"] = box2.Text;
drCurrentRow["Column3"] = box3.Text;
rowIndex++;
}
//add new row to DataTable
dtCurrentTable.Rows.Add(drCurrentRow);
//Store the current data to ViewState
ViewState["CurrentTable"] = dtCurrentTable;
//Rebind the Grid with the current data
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//Set Previous Data on Postbacks
SetPreviousData();
}
Setting up previous Data
private void SetPreviousData(){
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 1; i < dt.Rows.Count; i++)
{
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
box1.Text = dt.Rows[i]["Column1"].ToString();
box2.Text = dt.Rows[i]["Column2"].ToString();
box3.Text = dt.Rows[i]["Column3"].ToString();
rowIndex++;
}
}
}
}
Button click event Code
protected void ButtonAdd_Click(object sender, EventArgs e){
AddNewRowToGrid();
}
For Detail Tutorial Visit : geekswithblock
I have a gridview in web application which show textboxes in each columns in page load event. Now what I want to do is to add another label control in this itemtemplate. Show that when I type something in the textbox and click save, I can show the label instead of the textbox to my database. I got the saving part work fine but not sure how to show the text I typed in a label. What I have right now is after I clicked the save button, the textbox stay in the gridview and label not show up. Any idea how to fix this?
<asp:GridView ID='gvMain' ruant="server">
<Columns>
<asp:TemplateField HeaderText ="LastName">
<ItemTemplate>
<asp:TextBox ID="txtFName" runat="server"/>
<asp:Label ID="lblFName" ruant="server" />
</Columns>
</asp:GridView>
Please see this link for reference.
http://www.aspsnippets.com/Articles/Adding-Dynamic-Rows-in-ASP.Net-GridView-Control-with-TextBoxes.aspx
I would add both controls to a cell item template and hide/show them based on if I save a row or add a new one. So, my code would be like the following:
Markup:
<form id="form1" runat="server">
<div>
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Column1") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("Column2") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("Column3") %>'></asp:Label>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row"
OnClick="ButtonAdd_Click" />
<asp:Button ID="ButtonSave" runat="server" Text="Save"
OnClick="ButtonSave_Click" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
Code-behind:
private void SetInitialRow() {
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
Table = dt;
BindGrid();
SwitchMode(false);
}
private void AddNewRowToGrid() {
if(Table != null) {
DataRow row = Table.NewRow();
Table.Rows.Add(row);
BindGrid();
SwitchMode(false);
}
else {
Response.Write("ViewState is null");
}
}
private void SaveRow() {
if(Table != null) {
int rowIndex = Table.Rows.Count - 1;
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
Table.Rows[rowIndex]["Column1"] = box1.Text;
Table.Rows[rowIndex]["Column2"] = box2.Text;
Table.Rows[rowIndex]["Column3"] = box3.Text;
BindGrid();
SwitchMode(true);
}
else {
Response.Write("ViewState is null");
}
}
private void SwitchMode(bool add) {
Button saveBtn = (Button)Gridview1.FooterRow.Cells[3].FindControl("ButtonSave");
saveBtn.Visible = !add;
Button addBtn = (Button)Gridview1.FooterRow.Cells[3].FindControl("ButtonAdd");
addBtn.Visible = add;
SwitchControl(add);
}
private void SwitchControl(bool add) {
for(int i = 0; i < Table.Rows.Count; i++) {
bool txtVisible = false;
if (i == Table.Rows.Count - 1) {
txtVisible = !add;
}
TextBox box1 = (TextBox)Gridview1.Rows[i].Cells[1].FindControl("TextBox1");
box1.Visible = txtVisible;
TextBox box2 = (TextBox)Gridview1.Rows[i].Cells[2].FindControl("TextBox2");
box2.Visible = txtVisible;
TextBox box3 = (TextBox)Gridview1.Rows[i].Cells[3].FindControl("TextBox3");
box3.Visible = txtVisible;
Label label1 = (Label)Gridview1.Rows[i].Cells[1].FindControl("Label1");
label1.Visible = !txtVisible;
Label label2 = (Label)Gridview1.Rows[i].Cells[2].FindControl("Label2");
label2.Visible = !txtVisible;
Label label3 = (Label)Gridview1.Rows[i].Cells[3].FindControl("Label3");
label3.Visible = !txtVisible;
}
}
private DataTable Table {
get {
return ViewState["CurrentTable"] as DataTable;
}
set {
ViewState["CurrentTable"] = value;
}
}
private void BindGrid() {
Gridview1.DataSource = Table;
Gridview1.DataBind();
}
protected void Page_Load(object sender, EventArgs e) {
if(!Page.IsPostBack) {
SetInitialRow();
}
}
protected void ButtonAdd_Click(object sender, EventArgs e) {
AddNewRowToGrid();
}
protected void ButtonSave_Click(object sender, EventArgs e) {
SaveRow();
}
So, first I see the Grid with one row and I can populate it with data via TextBoxes and click Save. Then, TextBoxes become Labels and Add New Row is visible. If I click it, a new row with TextBoxes appears.
Ok,CLICK ME !
THis is what i have right now... but i want to add a delete functionality. I have added a delete command button column and on its click event i am deleting the particular row.
But my problem is that i am unable to retain the remaining row's values in the controls.
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
DataTable dtCurrentTable=new DataTable();
int RowIndex = e.RowIndex;
dtCurrentTable = (DataTable)ViewState["CurrentTable"];
dtCurrentTable.Rows.RemoveAt(e.RowIndex);
SetPreviousData1(dtCurrentTable);
}
private void SetPreviousData1(DataTable dtCurrentTable)
{
int rowIndex = 0;
if (dtCurrentTable != null)
{
DataTable dt = dtCurrentTable;
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
box1.Text = dt.Rows[i]["Column1"].ToString();
box2.Text = dt.Rows[i]["Column2"].ToString();
box3.Text = dt.Rows[i]["Column3"].ToString();
rowIndex++;
}
}
}
}
Please note i am not fetching anything from database.
UPDATE(rest of my code)
private void SetInitialRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
//Store the DataTable in ViewState
ViewState["CurrentTable"] = dt;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
private void AddNewRowToGrid()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
dtCurrentTable.Rows[i - 1]["Column1"] = box1.Text;
dtCurrentTable.Rows[i - 1]["Column2"] = box2.Text;
dtCurrentTable.Rows[i - 1]["Column3"] = box3.Text;
rowIndex++;
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["CurrentTable"] = dtCurrentTable;
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//Set Previous Data on Postbacks
SetPreviousData();
}
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
box1.Text = dt.Rows[i]["Column1"].ToString();
box2.Text = dt.Rows[i]["Column2"].ToString();
box3.Text = dt.Rows[i]["Column3"].ToString();
rowIndex++;
}
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
SetInitialRow();
}
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
AddNewRowToGrid();
}
ASPX
<asp:gridview ID="Gridview1" runat="server" ShowFooter="True" AutoGenerateColumns="False" OnRowDeleting="Gridview1_RowDeleting">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<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="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row"
onclick="ButtonAdd_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField DeleteText="D" HeaderText="D" ShowDeleteButton="true" />
</Columns>
</asp:gridview>
Update you gridview to following:
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<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="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row"
onclick="ButtonAdd_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkDel" OnCommand="DeleteRowHandler" Text="delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
Now add following code to you .cs page.
protected void DeleteRowHandler(object sender, CommandEventArgs e)
{
GridViewRow row = ((GridViewRow) ((LinkButton)sender).Parent.Parent);
DataTable dt = = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
for (int i = 0; i < Gridview1.Rows.Count; i++)
{
dr = dt.NewRow();
dr[1] = ((TextBox)Gridview1.Rows[i].Cells[1].FindControl("TextBox1")).Text;
dr[2] = ((TextBox)Gridview1.Rows[i].Cells[2].FindControl("TextBox1")).Text;
dr[3] = ((TextBox)Gridview1.Rows[i].Cells[3].FindControl("TextBox1")).Text;
dt.Rows.Add(dr);
}
dt.Rows.RemoveAt(row.RowIndex);
ViewState["CurrentTable"] = dt;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
You are missing the rebinding of the data to the gridview after deleting the row.
Inside the SetPreviousData1 function, add:
GridView1.DataSource=dtCurrentTable;
GridView1.DataBind();
I'm write the code which create new row in gridview when click button. The number of rows are created by value in textbox. Ex: When i enter value 2 in textbox, of course two rows will be added, but when i clicked button again, third rows still added. Please check my code here:
ASPX
<asp:TextBox ID="txtVisitor" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<ItemTemplate>
<asp:TextBox ID="txtDate" 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="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" OnClick="ButtonAdd_Click" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Code_Behind
protected void ButtonAdd_Click(object sender, EventArgs e)
{
int visitors = Convert.ToInt32(txtVisitor.Text);
AddNewRowToGrid(visitors);
}
private void SetInitialRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
//dr = dt.NewRow();
//Store the DataTable in ViewState
ViewState["CurrentTable"] = dt;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
private void AddNewRowToGrid(int visitors)
{
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow;
if (dtCurrentTable.Rows.Count > 0)
{
int rowindex = 0;
for (int i = 1; i < visitors; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowindex].Cells[1].FindControl("txtDate");
TextBox box2 = (TextBox)Gridview1.Rows[rowindex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowindex].Cells[3].FindControl("TextBox3");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
drCurrentRow["Column1"] = box1.Text;
drCurrentRow["Column2"] = box2.Text;
drCurrentRow["Column3"] = box3.Text;
dtCurrentTable.Rows.Add(drCurrentRow);
drCurrentRow = null;
rowindex++;
}
//add new row to DataTable
//Store the current data to ViewState
ViewState["CurrentTable"] = dtCurrentTable;
//Rebind the Grid with the current data
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetInitialRow();
}
}
Here is problem #1 with your code:
for (int i = dtCurrentTable.Rows.Count; i < visitors; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowindex].Cells[1].FindControl("txtDate");
TextBox box2 = (TextBox)Gridview1.Rows[rowindex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowindex].Cells[3].FindControl("TextBox3");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
drCurrentRow["Column1"] = box1.Text;
drCurrentRow["Column2"] = box2.Text;
drCurrentRow["Column3"] = box3.Text;
dtCurrentTable.Rows.Add(drCurrentRow);
drCurrentRow = null;
rowindex++;
}
you set i to 1
replace it to row count of gridview
tostart from it
Here is problem #1 with your code:
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowindex].Cells[1].FindControl("txtDate");
TextBox box2 = (TextBox)Gridview1.Rows[rowindex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowindex].Cells[3].FindControl("TextBox3");
This logic is flawed and not even necessary, because when you bind the grid it will iterate through the collection you supply as the DataSource and use the TemplateFields you defined in the markup to create each row.
The rows are not actually added to the GridView until is bound to a data source, a DataTable in your case, like this:
Gridview1.DataSource = dt;
Gridview1.DataBind();
Step #1 is to remove the FindControl lines from your AddNewRowToGrid method.
I am not even sure what you are trying to accomplish in your code.
I have a gridview in the popup, with 3 columns, out of which 2 are textbox column. I have added the textbox dynamically in the row data bound event. when data is entered and save button is clicked,the textboxes gets cleared and the empty values are saved. can any one one help me on this. thanks in advance
code here:
for (int r = 0; r < GridView2.Rows.Count; r++)
{
string sub_details = "";
string remarks = "";
GridViewRow gRow1 = GridView2.Rows[r];
// TextBox tb = (TextBox)gRow.Cells[2].FindControl("txt");
TextBox tb1 = (TextBox)gRow1.Cells[1].FindControl("txt1");
TextBox tb2 = (TextBox)gRow1.Cells[2].FindControl("txt2");
if (tb1 != null)
{
sub_details = tb1.Text;
TextBox1.Text = sub_details;
}
if (tb2 != null)
{
remarks= tb2.Text;
}
OdbcConnection DbConnection1 = new OdbcConnection(con1);
OdbcCommand DbCommand1 = DbConnection1.CreateCommand();
try
{
DbConnection1.Open();
DbCommand1.CommandText = "insert into tbl_campboss_report(site,tdate,entered_by,entered_time,details,camp_boss,sub_details,remarks)values('" + drpSites.SelectedItem.Text + "','" + txtDate.Text + "','" + Session["uname"].ToString() + "'," + ss + ",'" + lstDetails.SelectedItem.Text + "','" + txtCampBoss.Text + "','" + sub_details + "','" + remarks + "')";
int t1 = DbCommand1.ExecuteNonQuery();
if (t1 == 1)
{
DbConnection1.Close();
}
}
catch (Exception ee)
{
DbConnection1.Close();
}
}
You can achieve this task easily by placing your textboxes inside
template fields in your footer row with a save button. There you
can save these values to the database row by row.
Using CellIndex could fail if you add a column later to your gridview.
Your database code is prone to SQL injection, I advise you to use paramterized queries
Check below example
ASPX
<asp:GridView ID="gvCustomer" runat="server" AutoGenerateColumns="False"
ShowFooter="True" EmptyDataText="<h2>No records found </h2>"
onrowdeleting="gvCustomer_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="First name">
<FooterTemplate>
First Name:<asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="lblFirstName" Text='<%#Bind("FirstName") %>' runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Last name" >
<FooterTemplate>
Last Name:
<asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="lblLastName" Text='<%#Bind("LastName") %>' runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Favorite fruit">
<FooterTemplate>
Favorite fruit:
<asp:DropDownList ID="ddlFavFruit" runat="server">
<asp:ListItem Text="Apple" Value="1"></asp:ListItem>
<asp:ListItem Text="Mango" Value="2"></asp:ListItem>
<asp:ListItem Text="Orange" Value="3">Tomato</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="btnSave" runat="server" Text="Save"
onclick="btnSave_Click" />
</FooterTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddlFruits" runat="server" Enabled="False" selectedValue='<%#Bind("FruitID") %>'>
<asp:ListItem Text="Apple" Value="1"></asp:ListItem>
<asp:ListItem Text="Mango" Value="2"></asp:ListItem>
<asp:ListItem Text="Orange" Value="3">Tomato</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Codebehind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (ViewState["myData"] == null)
{
// initialize datatable
dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(int)));
dt.Columns.Add(new DataColumn("FirstName", typeof(string)));
dt.Columns.Add(new DataColumn("LastName", typeof(string)));
dt.Columns.Add(new DataColumn("FruitID", typeof(int)));
dt.Columns[0].AutoIncrement = true;
dt.Columns[0].AutoIncrementSeed = 1;
// Add sample data
for (int i = 0; i <= 5; i++)
{
DataRow dr = dt.NewRow();
dr["FirstName"] = "Scott";
dr["LastName"] = "Tiger";
dr["FruitID"] = "2";
dt.Rows.Add(dr);
}
ViewState["myData"] = dt;
}
else
{
dt = ViewState["myData"] as DataTable;
}
gvCustomer.DataSource = dt;
gvCustomer.DataBind();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
// fetch controls from footer
GridViewRow footerRow = ((Button)sender).NamingContainer as GridViewRow;
if (footerRow != null)
{
// Fetch footer controls
TextBox txtFirstName = footerRow.FindControl("txtFirstName") as TextBox;
TextBox txtLastName = footerRow.FindControl("txtLastName") as TextBox;
DropDownList ddlFruits = footerRow.FindControl("ddlFavFruit") as DropDownList;
// Save to datatable
dt = ViewState["myData"] as DataTable;
DataRow dr = dt.NewRow();
dr["FirstName"] = txtFirstName.Text.ToString();
dr["LastName"] = txtLastName.Text.ToString();
dr["FruitID"] = ddlFruits.SelectedValue;
dt.Rows.Add(dr);
gvCustomer.DataSource = dt;
gvCustomer.DataBind();
ViewState["myData"] = dt;
}
}
//This Metghod Will not Clear The Controls
//Keep this Method in Your .Aspx.cs Page
protected override void CreateChildControls()
{
base.CreateChildControls();
// Keep your GridView Binding Code
}