Binding a DataTable to Template Fields of a GridView - c#

I can successfully bind a DataTable to a GridView by auto generating columns, but I need to display a multi-lined cell for one of the columns. To do this, I want to use a template field with an item template using a TextBox object. I fill in the DataTable by adding columns and then adding the rows. I know my datatable is set up right because it shows all the data (except for the multi-lined cell) as I want it. My issue is getting the gridview to extract my data based on the column names and filling in the template fields I have set up. If I turn AutoGenerateColumns off then the 4 templatefield columns still appear (in the correct amount according to the datatable too), just blank, and if I have it set to true, then the 4 blank columns appear as well as 4 additional columns with the same headers that contain my data using the defaults for what the cell contains to display the information.
<asp:GridView ID="DataGrid1" runat="server" AutoGenerateColumns="False" HeaderStyle-BorderStyle="None" CellPadding="3" ItemStyle-Wrap="true" >
<Columns>
<asp:TemplateField HeaderText="Code">
<asp:ItemTemplate>
<asp:Label ID="txtCode" runat="server" Text='<%# Eval("Code") %>'>
</asp:Label>
</asp:ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title">
<asp:ItemTemplate>
<asp:Label ID="txtTitle" runat="server" Text='<%# Eval("Title") %>'>
</asp:Label>
</asp:ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Class">
<asp:ItemTemplate>
<asp:Label ID="txtClass" runat="server" Text='<%# Eval("Class") %>'>
</asp:Label>
</asp:ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="History">
<asp:ItemTemplate>
<asp:TextBox ID="txtHistory" runat="server" IsReadOnly="true" Text='<%# Eval("History")%>'>
</asp:TextBox>
</asp:ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The above is the portion of my asp.net code that relates to the GridView in question. Following is how i set up my DataTable and bind it.
DataTable table = new DataTable();
table.Columns.Add("Code", typeof(string));
table.Columns.Add("Title", typeof(string));
table.Columns.Add("Class", typeof(string));
table.Columns.Add("History", typeof(string));
for (int i = 0; i < index; i++)
{
table.Rows.Add(docs[i].Code, docs[i].Name, docs[i].Class.Name, history[i]);
}
DataGrid1.DataSource = table;
DataGrid1.DataBind();

Change .aspx code like below
<Columns>
<asp:TemplateField HeaderText="Code">
<ItemTemplate>
<asp:Label ID="txtCode" runat="server" Text='<%# Eval("Code") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title">
<ItemTemplate>
<asp:Label ID="txtTitle" runat="server" Text='<%# Eval("Title") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Class">
<ItemTemplate>
<asp:Label ID="txtClass" runat="server" Text='<%# Eval("Class") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="History">
<ItemTemplate>
<asp:TextBox ID="txtHistory" runat="server" IsReadOnly="true"
Text='<%# Eval("History")%>'>
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>

foreach (GridViewRow grdRow in grdMenuPermitted.Rows)
{
DataRow drow = dt.NewRow();
Label lblMenuName = (Label)grdRow.FindControl("lblMenuName");
HiddenField hdnID = (HiddenField)grdRow.FindControl("hdnID");
drow["MenuName"] = lblMenuName.Text;//grdRow.Cells[0].Text;
drow["MenuID"] = hdnID.Value;
//drow["lname"] = grdRow.Cells[3].Text;
dt.Rows.Add(drow);
}

Related

Get cell values of textBoxes within ItemTemplate of a Gridview

I have a GridView with textBoxes inside ItemTemplates. I can retrieve the data from the column that was binded to the Gridview on page load, however, I do not see any of the manually entered text when reading the cell values.
The HTML:
<asp:GridView ID="tblRentDue" runat="server" ClientIDMode="Static">
<Columns>
<asp:BoundField DataField="Application_ID" HeaderText="Application ID" HeaderStyle-Wrap="false" />
<asp:BoundField DataField="Month" HeaderText="Month" HeaderStyle-Wrap="false" />
<asp:TemplateField HeaderText="Orignal Amount Due">
<ItemTemplate>
<asp:TextBox ID="txtOrignalAmountDue" runat="server" TextMode="Number" Text='<%# Eval("Original_Amount_Due") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fees Due">
<ItemTemplate>
<asp:TextBox ID="txtFeesDue" runat="server" TextMode="Number" Text='<%# Eval("Fees_Due") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Amount Paid">
<ItemTemplate>
<asp:TextBox ID="txtAmountPaid" runat="server" TextMode="Number" Text='<%# Eval("Amount_Paid") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Total Still Due">
<ItemTemplate>
<asp:TextBox ID="txtTotalStillDue" runat="server" TextMode="Number" Text='<%# Eval("Total_Still_Due") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The code behind:
public DataTable GetDataTable(GridView dtg)
{
DataTable dt = new DataTable();
dt.Columns.Add("Month");
dt.Columns.Add("Original_Amount_Due");
dt.Columns.Add("Fees_Due");
dt.Columns.Add("Amount_Paid");
dt.Columns.Add("Total_Still_Due");
foreach (GridViewRow row in dtg.Rows)
{
DataRow dr;
dr = dt.NewRow();
dr["Month"] = (row.Cells[0].Text); //These values are showing up and was loaded from the database.
dr["Original_Amount_Due"] = (row.Cells[1].Text); //Nothing showing from user input
dr["Fees_Due"] = (row.Cells[2].Text); //Nothing showing from user input
dr["Amount_Paid"] = (row.Cells[3].Text); //Nothing showing from user input
dr["Total_Still_Due"] = (row.Cells[4].Text); //Nothing showing from user input
dt.Rows.Add(dr);
}
return dt;
}
The solution I found - within the foreach loop for each textbox:
TextBox orignalAmount = (TextBox)row.Cells[1].FindControl("txtOrignalAmountDue");
dr["Original_Amount_Due"] = orignalAmount.Text;
There may be a less clunky way of doing this but it does work.

Insert Grid View column value into Textbox and dropdown on button control

I want to Fill gridview column value into given control
something like Project Title value fill inside project Title text box Problem ID fill inside Selected Problem Dropdown and so on... on button click even
i have taken as control name
Project title as txtProjectTitle,
selectProblem Id as ddlSelectProblem,
Project_Start_Date as txtProjectStartDate,
Project_Target_Date as TextBox1,
gridview as GrdTemp,
Procedd button as Button2_Click
ASPX CODE:
[![<asp:GridView ID="GrdTemp" runat="server" Style="width: 100%; text-align: center" class="table table-striped table-bordered" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="S.No." HeaderStyle-Width="5%">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ID" Visible="false">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("ID") %>' ID="lblID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Project Title">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("Project_Title") %>' ID="lblID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Problem ID">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("Problem") %>' ID="lblID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Project Start Date">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("Project_Start_Date") %>' ID="lblID</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Project Target Date">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("Project_Target_Date") %>' ID="lblID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns> </asp:GridView>][2]][2]
C# code:
protected void Button2_Click(object sender, EventArgs e)
{
GridViewRow row = (sender as Label).NamingContainer as GridViewRow;
TextBox txtProject = row.FindControl("txtProjectTitle") as TextBox;
txtProject.Text = Convert.ToString((row.Parent.Parent as GridView).DataKeys[row.RowIndex]["Project_Title"]);
DropDownList ddlProblem = row.FindControl("ddlSelectProblem") as DropDownList;
ddlSelectProblem.SelectedItem.Text = Convert.ToString((row.Parent.Parent as GridView).DataKeys[row.RowIndex]["Problem"]);
txtProjectStartDate.Text = Convert.ToString((row.Parent.Parent as GridView).DataKeys[row.RowIndex]["Project_Start_Date"]);
TextBox1.Text = Convert.ToString((row.Parent.Parent as GridView).DataKeys[row.RowIndex]["Project_Target_Date"]);
}

How to fill data in some of GridViewRow and leave some blank

ASP.net C#
I am creating a gridview having 5 rows containing detail of operations users have to perform. Detail of operations should be filled when it is completed. At a time any number of operation details can be filled.
In gridview, first Item-template contains Label (for operation name) and others are textbox (for other details).
If any user has filled 3 rows then rest of two rows should be blank.
My problem is how to bind those 3 rows filled previously leaving two bottom rows available for entry.
My Gridview design is :
<asp:GridView CssClass="table-bordered gridStyle" runat="server" ShowFooter="True"
ID="grdOperationEntry" GridLines="None" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Operation">
<ItemTemplate>
<asp:Label Text='<%# Eval("operation_title") %>' ID="lblOperationName" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date of Completion">
<ItemTemplate>
<asp:TextBox runat="server" Text='<%# Eval("date_completed") %>' CssClass="form-control"
ID="txtDateCompletion" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Time Taken">
<ItemTemplate>
<asp:TextBox runat="server" Text='<%# Eval("time_taken") %>' ID="txtTimeTaken" CssClass="form-control" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Score">
<ItemTemplate>
<asp:TextBox runat="server" Text='<%# Eval("score_gain") %>' ID="txtScore" CssClass="form-control" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Reported To">
<ItemTemplate>
<asp:TextBox runat="server" Text='<%# Eval("reported_to") %>' ID="txtReportedTo"
CssClass="form-control" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<AlternatingRowStyle BackColor="White" />
<EditRowStyle BackColor="#7C6F57" />
</asp:GridView>
Add a Label with all TextBoxes in GridView and set them visible false and bind also Label from database. I have added an example TemplateField to below, you can do it for all other:
.....
<asp:TemplateField HeaderText="Date of Completion">
<ItemTemplate>
<asp:Label runat="server" Visible="False" Text='<%# Eval("date_completed")
ID="lblDateCompletion" %>'></asp:Label>
<asp:TextBox runat="server" Visible="False" Text='<%# Eval("date_completed") %>'
ID="txtDateCompletion" />
</ItemTemplate>
</asp:TemplateField>
.....
In RowDataBound event set them visible true:
protected void grdOperationEntry_RowDataBound(object sender, GridViewRowEventArgs e)
{
// check if gridview row not a header or footer
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get controls by id from gridview and cast them
Label lblDateCompletion = e.Row.FindControl("lblDateCompletion") as Label;
TextBox txtDateCompletion = e.Row.FindControl("txtDateCompletion") as TextBox;
if (lblDateCompletion.Text == null)
txtDateCompletion.Visible = true;
else
lblDateCompletion.Visible = true;
// perform same for other controls
}
}
Note: Don't forget to add OnRowDataBound property to your GridView <asp:GridView ID="grdOperationEntry" runat="server" OnRowDataBound="grdOperationEntry_RowDataBound" >

using checkbox to select and delete row from gridiew datasource = session C# .net

I have been searching on here and other sites for three days for a solution. I need to select one or more rows (using checkbox) and delete selected row(s) from a gridview who's datasource is a session datatable as you will see. Not interested in SQLConnections or LINQ Entities. As a result I am not sure if I need to use e.commandarguments, or how to go about it, but I have tried them with no luck.
Error is visible and clearly commented on CART.ASPX.CS page inside the following method
if (chkRemCart != null && chkRemCart.Checked)
Any assistance would be greatly appreciated and if you require any further coding or explanations to help with a solution, just ask.
Thank you in advance.
CART.ASPX
<asp:GridView ID="gvCart" runat="server" AutoGenerateColumns="False" ShowHeaderWhenEmpty="true" CellPadding="4"
HeaderStyle-CssClass="header" EmptyDataText="You have successfully cleared your Shopping Cart"
OnRowDataBound="gvCart_RowDataBound" >
<Columns>
<asp:TemplateField HeaderText="Movie Selector">
<ItemTemplate>
<asp:CheckBox ID="chkRemCart" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Movie ID">
<ItemTemplate>
<asp:Label ID="lblMovieID" runat="server" Text='<%# Eval("MovieId") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Duration">
<ItemTemplate>
<asp:Label ID="lblDuration" runat="server" Text='<%# Eval("Duration") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Genre">
<ItemTemplate>
<asp:Label ID="lblGenre" runat="server" Text='<%# Eval("Genre") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Rating">
<ItemTemplate>
<asp:Label ID="lblRating" runat="server" Text='<%# Eval("Rating") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price">
<ItemTemplate>
<asp:Label ID="lblPrice" runat="server" Text='<%# Eval("Price","{0:n}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:Label ID="lblDescription" runat="server" Text='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label ID="lblTotal" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnRem" runat="server" OnClick="RemCart" Text="Remove Selection" CssClass="button" Title="Remove Movies From Cart" />
CART.ASPX.CS
Page_Load calling RefreshPages() method. gvCart displaying all columns and rows of items in Datasource/Session/Datatable
public void RefreshPages()
{
if (Session["SelectedMovies"] != null)
{
DataTable MovieTable = (DataTable)Session["SelectedMovies"];
gvCart.DataSource = MovieTable;
gvCart.DataBind();
}
}
protected void RemCart(object sender, EventArgs e)
{
// Check session exists
if (Session["selectedMovies"] != null)
{
// Opening / Retreiving DataTable.
DataTable MovieTable = (DataTable)Session["SelectedMovies"];
foreach (GridViewRow row in gvCart.Rows)
{
CheckBox chkRemCart = row.Cells[0].FindControl("chkRemCart") as CheckBox;
if (chkRemCart != null && chkRemCart.Checked)
{
// Error appearing on line below. Scroll right to read.
int MovieId = Convert.ToInt32(gvCart.DataKeys[row.RowIndex].Value); // Error here. //Additional information: Index was out of range. Must be non - negative and less than the size of the collection.
MovieTable.Rows.RemoveAt(row.RowIndex);
//Saving session
Session["selectedMovies"] = MovieTable;
// Updating gvCart
gvCart.DataSource = MovieTable;
gvCart.DataBind();
}
}
}
}
Assign DataKeyNames="PrimaryKey" in gridview like below and check
<asp:GridView ID="gvCart" runat="server" AutoGenerateColumns="False" ShowHeaderWhenEmpty="true" DataKeyNames="MovieId" CellPadding="4"
HeaderStyle-CssClass="header" EmptyDataText="You have successfully cleared your Shopping Cart"
OnRowDataBound="gvCart_RowDataBound" >
<Columns>
<asp:TemplateField HeaderText="Movie Selector">
<ItemTemplate>
<asp:CheckBox ID="chkRemCart" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Movie ID">
<ItemTemplate>
<asp:Label ID="lblMovieID" runat="server" Text='<%# Eval("MovieId") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Duration">
<ItemTemplate>
<asp:Label ID="lblDuration" runat="server" Text='<%# Eval("Duration") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Genre">
<ItemTemplate>
<asp:Label ID="lblGenre" runat="server" Text='<%# Eval("Genre") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Rating">
<ItemTemplate>
<asp:Label ID="lblRating" runat="server" Text='<%# Eval("Rating") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price">
<ItemTemplate>
<asp:Label ID="lblPrice" runat="server" Text='<%# Eval("Price","{0:n}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:Label ID="lblDescription" runat="server" Text='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label ID="lblTotal" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
code behind:
public void RefreshPages()
{
if (Session["SelectedMovies"] != null)
{
DataTable MovieTable = (DataTable)Session["SelectedMovies"];
gvCart.DataSource = MovieTable;
gvCart.DataBind();
}
}
protected void RemCart(object sender, EventArgs e)
{
// Check session exists
if (Session["selectedMovies"] != null)
{
// Opening / Retreiving DataTable.
DataTable MovieTable = (DataTable)Session["SelectedMovies"];
foreach (GridViewRow row in gvCart.Rows)
{
CheckBox chkRemCart = row.Cells[0].FindControl("chkRemCart") as CheckBox;
if (chkRemCart != null && chkRemCart.Checked)
{
// Error appearing on line below. Scroll right to read.
int MovieId = Convert.ToInt32(gvCart.DataKeys[row.RowIndex].Value); // Error here. //Additional information: Index was out of range. Must be non - negative and less than the size of the collection.
DataRow[] drs = dt.Select("MovieId = '" + MovieId + "'"); // replace with your criteria as appropriate
if (drs.Length > 0)
{
MovieTable.Rows.Remove(drs[0]);
}
}
}
//Saving session
Session["selectedMovies"] = MovieTable;
// Updating gvCart
gvCart.DataSource = MovieTable;
gvCart.DataBind();
}
}

FindControl in gridview returns null

I am currently in a dilemma with my gridview not returning a label, which is within a detailsview...
My C# code is:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
// get pet number for when removing a pet from reservation
int numberSelected = -1;
String numbertxt = "-1";
GridView gv1 = (GridView)sender;
GridViewRow rvRow = gv1.Rows[gv1.SelectedRow.RowIndex];
Label numberLbl = (Label)rvRow.Cells[0].FindControl("lblNumber");
// find selected index, and get number in column 0
// label within GridView1 within dvReservation DetailsView
numbertxt = numberLbl.Text;
...
Gridview:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="dsObjGet"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField InsertVisible="False" ShowHeader="False">
<AlternatingItemTemplate>
<asp:Label ID="lblNumber" runat="server"
Text='<%# Eval("NUMBER") %>' Visible="False"></asp:Label>
</AlternatingItemTemplate>
<ItemTemplate>
<asp:Label ID="lblNumber" runat="server"
Text='<%# Eval("NUMBER") %>' Visible="False"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<AlternatingItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("NAME") %>'>
</asp:Label>
</AlternatingItemTemplate>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("NAME") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField SelectText="Remove" ShowSelectButton="True"
CausesValidation="False">
<ControlStyle CssClass="link" />
</asp:CommandField>
</Columns>
</asp:GridView>
When I breakpoint
Label numberLbl = (Label)rvRow.Cells[0].FindControl("lblNumber");
the label comes out as null (numberLbl)...
The message returned from the exception is:
"Object reference not set to an instance of an object"
EDIT:
This seems to be resolved if I generate lblNumber in an external gridview (on the page) with Eval("NUMBER"), though I don't see why it doesn't work in the current GridView I was trying to work with, given that GridView1 is within a DetailsView.
You should not use the Cell Collection when using FindControl. Just use this
GridView gv1 = (GridView)sender;
GridViewRow rvRow = gv1.SelectedRow;
Label numberLbl = (Label)rvRow.FindControl("lblNumber");

Categories