I am using a gridview, and here is one of my templatefields:
<asp:TemplateField HeaderText="Quantity" SortExpression="Quantity">
<HeaderTemplate>
<asp:Label ToolTip="Quantity" runat="server" Text="Qty"></asp:Label>
</HeaderTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_Quantity" runat="server" Text='<%# Bind("Quantity") %>' Width="30px"
Enabled='True'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
I am tring to reach txt_Quantity like this
protected void begv_OrderDetail_RowCreated(object sender, GridViewRowEventArgs e)
{
TextBox txt_Quantity = (TextBox)e.Row.FindControl("txt_Quantity");
txt_Quantity.Attributes.Add("onFocus", "test(this)");
}
This is the error message:
System.NullReferenceException: Object reference not set to an instance of an object.
RowCreated
is executed for every RowType
(btw, the same as with RowDataBound
), so for the header, data-row, footer or pager.
The first row is the header-row, but the TextBox
is in rows with RowType
=DataRow
. Since it's in the EditItemTemplate
you also have to check the EditIndex
:
protected void begv_OrderDetail_RowCreated(object sender, GridViewRowEventArgs e)
{
if (row.RowType == DataControlRowType.DataRow
&& e.Row.RowIndex == begv_OrderDetail.EditIndex)
{
TextBox txt_Quantity = (TextBox)e.Row.FindControl("txt_Quantity");
txt_Quantity.Attributes.Add("onFocus", "test(this)");
}
}
Note that if you enumerate the Rows
property of the GridView
you only get the rows with RowType
=DataRow
, so the header, footer and pager are omitted. So here no additional check is needed:
foreach(GridViewRow row in begv_OrderDetail.Rows)
{
// only DataRows
}