I have a gridview with two textboxes in the footer. What's required is get the textbox values, store it to a datatable and then bind the same to the gridview. I am unable to get the textbox values. They show up empty (as you can see). Where am I going wrong.
ASPX:
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="False"
ShowFooter="true" OnRowDataBound="gv_RowDataBound"
OnRowCommand="gv_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkEdit" runat="server" Text="Edit" CommandName="Edit">
</asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="lnkUpdate" runat="server" Text="Update"
CommandName="Update"></asp:LinkButton>
<asp:LinkButton ID="lnkCancel" runat="server" Text="Cancel"
CommandName="Cancel"></asp:LinkButton>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="S.No">
<ItemTemplate>
<%#Container.DataItemIndex %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="lbId" runat="server" Text='<%#Eval("id") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtId" runat="server" Text='<%#Eval("id") %>'>
</asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtNewId" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtNewId"
SetFocusOnError="true"
ErrorMessage="*" ForeColor="Red"></asp:RequiredFieldValidator>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="NAME">
<ItemTemplate>
<asp:Label ID="lbName" runat="server" Text='<%#Eval("name") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtName" runat="server" Text='<%#Eval("name") %>'>
</asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtNewName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="txtNewName" SetFocusOnError="true"
ErrorMessage="*" ForeColor="Red"></asp:RequiredFieldValidator>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDelete" runat="server" Text="Delete"
CommandName="Delete"></asp:LinkButton>
</ItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="lnkInsert" runat="server" Text="Insert"
CommandName="Insert" ></asp:LinkButton>
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CS:
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
DataTable dt = new DataTable();
switch (e.CommandName)
{
case "Insert":
GridViewRow fRow = gv.FooterRow;
dt.Columns.Add("id");
dt.Columns.Add("name");
dt = (DataTable)ViewState["students"];
DataRow dr = dt.NewRow();
dr["id"] = ((TextBox)fRow.FindControl("txtNewId")).Text;
dr["name"] = ((TextBox)fRow.FindControl("txtNewName")).Text;
dt.Rows.Add(dr);
ViewState["students"] = dt;
gv.DataSource = ViewState["students"];
gv.DataBind();
break;
}
}
The textboxes are txtNewId, txtNewName.
Do not use grid_Row command for insert. Use button click event
like this. It will solve your problem
protected void OnCmdInsertClick(object sender, EventArgs e)
{
//Grid's footer row
var footerRow = gv.FooterRow;
if(footerRow !=null)
{
//get your textbox instances
var txtNewId = (TextBox) footerRow.FindControl("txtNewId");
var txtNewName = (TextBox) footerRow.FindControl("txtNewName");
// Check for null
if(txtNewId !=null && txtNewName !=null)
{
var dt = (DataTable)ViewState["students"];
DataRow dr = dt.NewRow();
dr["id"] = txtNewId.Text;
dr["name"] = txtNewName.Text;
dt.Rows.Add(dr);
ViewState["students"] = dt;
gv.DataSource = ViewState["students"];
gv.DataBind();
}
}
}
In the button click event, use the following to get the actual GridViewRow of the footerL
protected void insertButton_Click(object sender, EventArgs e)
{
// This is the crux -
GridViewRow row = (GridViewRow)((sender as Button).NamingContainer);
// ...
// then you can get your textboxes
// Since we know it's an insert
dt.Columns.Add("id");
dt.Columns.Add("name");
dt = (DataTable)Session["students"];
DataRow dr = dt.NewRow();
TextBox txtnewid = (TextBox) row.FindControl("txtNewId");
TextBox txtnewName = (TextBox) row.FindControl("txtNewName");
dr["id"] = txtnewid.Text;
dr["name"] = txtnewName.Text ;
dt.Rows.Add(dr);
Session["students"] = dt;
gv.DataSource = dt;
gv.DataBind();
}
EDIT The reason viewstate didn't work is because the viewstate lasts only between postbacks. Sessions stay alive for the duration of the user's session. The default is 20 minutes of idle time.
You would normally use ViewState for persisting data between pages during a postback.
This doesn't address best practice, it's just what it is.
Please check whether you are binding the grid view correctly in the Page Load. What i mean to say is whether you are binding with in the if condidtion
if(!IspostBack)
{
BindGridView();
}
I hope this helps. Check it out..
To bind the footer with data, use the below code
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Footer)
{
TextBox txtNewId = (TextBox)e.Row.FindControl("txtNewId");
txtNewId.Text = "New 01";
}
}
...and to retrieve value from the footer textbox,
TextBox txtNewId = (TextBox)gvGrid.FooterRow.FindControl("txtNewId");
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
DataTable dt = new DataTable();
if (e.CommandName.Equals("Insert"))
{
GridViewRow fRow = gv.FooterRow;
dt.Columns.Add("id");
dt.Columns.Add("name");
dt = (DataTable)ViewState["students"];
DataRow dr = dt.NewRow();
TextBox txtnewid = (TextBox) fRow.FindControl("txtNewId");
TextBox txtnewName = (TextBox) fRow.FindControl("txtNewName");
dr["id"] = txtnewid.Text;
dr["name"] = txtnewName.Text ;
dt.Rows.Add(dr);
ViewState["students"] = dt;
gv.DataSource = ViewState["students"];
gv.DataBind();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With