FindControl in gridview returns null - c#

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");

Related

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" >

How to put each cell value for each row from GridView in variables

I tried some ways in stackoverflow solutions. But Those are not implemented well by me. Most of the time I got null/empty for the variables and Exception like "Object reference not set to an instance of an object."
My GridView:
<asp:GridView runat="server" ID="TestReportGridView" AutoGenerateColumns="false" Width="370px">
<Columns>
<asp:TemplateField HeaderText="ID" Visible="false">
<ItemTemplate>
<%#Eval("TestId") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sr">
<ItemTemplate>
<%#Container.DataItemIndex+1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Test">
<ItemTemplate>
<%#Eval("TestName") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fee">
<ItemTemplate>
<%#Eval("Fee") %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle HorizontalAlign="Left" />
</asp:GridView>
I want to put cell text in 4 different variables for each row when I click in Save button:
protected void SaveButton_Click(object sender, EventArgs e)
{
string patient = PatientNameTextBox.Text;
string birthDate = BirthDateTextBox.Text;
string mobile = MobileNoTextBox.Text;
int rows = TestReportGridView.Rows.Count;
foreach (GridViewRow row in TestReportGridView.Rows)
{
Label test = (Label)row.FindControl("Test");
string testName = test.Text;
//Label lblQuantity = (Label)row.FindControl("Quantity");
//string Quantity = lblQuantity.Text;
}
}
Image of the UI
I added a label in ItemTemplate. does it right way to add Label
<asp:TemplateField HeaderText="Test">
<ItemTemplate>
<asp:Label ID="Test" runat="server" ><%#Eval("TestName") %></asp:Label>
</ItemTemplate>
</asp:TemplateField>
You need to add Label control in your ItemTemplate. An example below:
<ItemTemplate>
<asp:Label ID="Test" runat="server" Text='<%# Eval("TestName") %>' />
</ItemTemplate>
Adding <%#Eval("TestId") %> directly inside ItemTemplate will not automatically add any control to search from code behind.

Update column value while binding in gridview

I'd like to update the values of column Action based on the value of the column Status which is Boolean. If Status is True then value in Action must update to Deactivate. When I run, the Action field doesn't updates. I think there is an error in codebehind.
Here is the codebehind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string value = e.Row.Cells[4].Text;
TextBox TextBox2 = (TextBox)e.Row.FindControl("TextBox2");
if (value == "True")
{
TextBox2.Text = "Take";
}
else if (value == "False")
{
TextBox2.Text = "Available";
}
}
}
Here is the code:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
AllowSorting="True"
onselectedindexchanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="ShopNumber" HeaderText="ShopNumber" ItemStyle-Width="80" SortExpression="ShopNumber" >
</asp:BoundField>
<asp:BoundField DataField="ShopName" HeaderText="ShopName" ItemStyle-Width="80" SortExpression="ShopName" >
</asp:BoundField>
<asp:BoundField DataField="Address" HeaderText="Address" ItemStyle-Width="80"SortExpression="Address" >
</asp:BoundField>
<asp:BoundField DataField="Website" HeaderText="Website" ItemStyle-Width="80" SortExpression="Website" >
</asp:BoundField>
<asp:TemplateField HeaderText="Status" SortExpression="Status">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Status") %>'> </asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Status") %>'> </asp:TextBox>
</EditItemTemplate>
<ItemStyle Width="80px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Action" SortExpression="Action">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Action") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Action") %>'> </asp:TextBox>
</EditItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You have a couple issues. First, you are trying to update the "Status" column by setting the text of TextBox2. In your question, you wanted to update the "Action" column.
Your second issue is that you are trying to update the TextBox in the EditItemTemplate of the column. On first run of the GridView, this template will not be shown. It will only be shown when the GridView is put into edit mode. What this means is that TextBox2 shouldn't even be found.
What you need to do is first use the the correct column, whichever that may be. If that truly is the "Action" column, first try setting the Label1 text value. If your GridView is in edit mode, set the TextBox1 text value instead.
You also have two EditItemTemplate in your "Action" column. You probably don't want that and that may be causing an error.

Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index in C# asp.Net

I am implementing Grid View in my application...When i try to delete a record from the Grid View it throws this error:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
This is my Server side Code:
protected void gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
foreach (GridViewRow gv in gridview1.Rows)
{
CheckBox check = (CheckBox)gv.FindControl("deleteall");
if (check.Checked)
{
con.Open();
if (gridview1.DataKeys != null)
{
**In this line only the error occurs**
int RegNo = Convert.ToInt32(gridview1.DataKeys[gv.RowIndex].Value);
}
cmd = new MySqlCommand("delete from studentinfo where Regno='" + 1 + "'", con);
// cmd.Parameters.Add("#id", RegNo);
cmd.ExecuteNonQuery();
con.Close();
}
}
}
My Client Side Grid :
<asp:GridView ID="gridview1" runat="server" AutoGenerateColumns="False" AllowSorting="True" onrowdeleting="gridview1_RowDeleting" SelectedIndex="1">
<Columns>
<asp:TemplateField HeaderText="Delete All">
<ItemTemplate>
<asp:CheckBox ID="deleteall" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Register Number">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("RegNo") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("RegNo") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Section">
<EditItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("Section") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Section") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" />
</Columns>
</asp:GridView>
Can any one pls help me sove this problem by providing some ideas or sample code...
The datakeys collection itself may not be null, but it can contain zero elements. In this example, your grid doesn't set the DataKeyNames property, so this grid isn't tracking any datakeys (the collection will be empty). That is probably why you are getting an index error.
You should set the DataKeyNames property. In your code you also need to check to make sure the collection contains elements.

Categories