Need help with accessing a control within a template field

  • Thread starter Thread starter Siva
  • Start date Start date
S

Siva

Hello
I have a dropdownlist inside the gridview as a template column defined
as follows:
<asp:TemplateField HeaderText="Choose Location">
<ItemTemplate>
<asp:DropDownList ID="ddlChooseLoc" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
I have the gridview inside of a master page- content hierarchy.
I have declared the CodeFileBaseClass in your @ Page directive; I have
also declared a variable of the type dropdownlist in the base class.
When I try to access it from the partial class I am getting a null
value for the dropdownlist variable.
I even tried to a FindControl on the dropdownlist still I am getting a
null.
Any idea what I may be missing?
Thanks
-Siva
 
I am not sure how the Master Page bit fits into this problem because you
havn't said where you are trying to access the GridView from and where the
GridView is (i.e. master or child page for both questions).

Generally the problem with accessing a control within a GridView
TemplateField is that there are lots of the (i.e. one on each row) so you
can't use GridView.FindControl("ChildControlID");.

What you have to do is use find control on a particular row e.g.

GridView.Rows[2].FindControl("ChildControlId");

If you want to set a property on a control based on a set of criteria a good
place to do it is in the RowDataBound event handler. For example the below
code sets the colour of a lable control to Red when the text Value = Invalid
Product

protected void gvwOrderDetails_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (((Label)e.Row.FindControl("lblDescription")) != null)
{
if (((Label)e.Row.FindControl("lblDescription")).Text ==
"Invalid Product")
{
((Label)e.Row.FindControl("lblDescription")).ForeColor =
System.Drawing.Color.Red;
lblInvalidProduct.Visible = true;
btnNext4.Visible = false;
}
}
}

Please note that i also check to see if the control i am looking for is set
to null to account for rows such as headers etc that don't contain the
control i am looking for.
 
Thank you for the reply. Actually as a matter of fact I am trying the
access the dropdown control from the Row_DataBound method.
I am also trying to do the FindControl on the row I am trying to update
like this:

ddl2 = (DropDownList)e.Row.FindControl("ddlChooseLoc");---> at this
point I am getting
a null value for ddl2

I have defined the variable ddl2 in the base class file (which is
inherited from Page class
placed under app_code folder and my partial class derives from this
base class) as follows:
protected DropDownList ddl2;
I have the CodeBasefile in the @Page set to the base class.

Here is a part of my aspx page:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="OrderTable.aspx.cs"
Inherits="OrderTable" Title="Untitled Page"
CodeFileBaseClass="OrderTable_Base"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
Runat="Server">
<asp:GridView ID="GridView1" runat="server"
DataSourceID="ObjectDataSource1" AllowPaging="True"
AutoGenerateColumns="False" AllowSorting="True"
AutoGenerateEditButton="True"
OnRowDataBound="GridView1_RowDataBound"
OnRowUpdating = "GridView1_RowUpdating"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
</Columns>
<asp:TemplateField HeaderText="Choose Location">
<ItemTemplate>
<asp:DropDownList ID="ddlChooseLoc" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>

Thanks
-Siva
I am not sure how the Master Page bit fits into this problem because you
havn't said where you are trying to access the GridView from and where the
GridView is (i.e. master or child page for both questions).

Generally the problem with accessing a control within a GridView
TemplateField is that there are lots of the (i.e. one on each row) so you
can't use GridView.FindControl("ChildControlID");.

What you have to do is use find control on a particular row e.g.

GridView.Rows[2].FindControl("ChildControlId");

If you want to set a property on a control based on a set of criteria a good
place to do it is in the RowDataBound event handler. For example the below
code sets the colour of a lable control to Red when the text Value = Invalid
Product

protected void gvwOrderDetails_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (((Label)e.Row.FindControl("lblDescription")) != null)
{
if (((Label)e.Row.FindControl("lblDescription")).Text ==
"Invalid Product")
{
((Label)e.Row.FindControl("lblDescription")).ForeColor =
System.Drawing.Color.Red;
lblInvalidProduct.Visible = true;
btnNext4.Visible = false;
}
}
}

Please note that i also check to see if the control i am looking for is set
to null to account for rows such as headers etc that don't contain the
control i am looking for.
Siva said:
Hello
I have a dropdownlist inside the gridview as a template column defined
as follows:
<asp:TemplateField HeaderText="Choose Location">
<ItemTemplate>
<asp:DropDownList ID="ddlChooseLoc" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
I have the gridview inside of a master page- content hierarchy.
I have declared the CodeFileBaseClass in your @ Page directive; I have
also declared a variable of the type dropdownlist in the base class.
When I try to access it from the partial class I am getting a null
value for the dropdownlist variable.
I even tried to a FindControl on the dropdownlist still I am getting a
null.
Any idea what I may be missing?
Thanks
-Siva
 
OK, lets forget about master page, base class et all. I just created a
simple website in ASP.Net 2.0 with a gridview with a template field
and tried to place a dropdownlist control in it. In my Row_DataBound
method, when I try to access it using FindControl , I am getting a
null.
Here is my aspx page:
*********************************************
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server"
DataSourceID="XmlDataSource1" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="location">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1"
runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server"
DataFile="~/App_data/data.xml">
</asp:XmlDataSource>

</div>
</form>
</body>
</html>
***********************************************
Here is my code behind:
*************************************************
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
DropDownList ddl =
(DropDownList)e.Row.FindControl("DropDownList1");
ArrayList al = new ArrayList();
al.Add("1");
al.Add("2");
ddl.DataSource = al;
ddl.DataBind();
}
}

The line where it does e.Row.FindControl , it returns a null for the
ddl variable.
The same code used to work (of course inside of a datagrid) very well
in asp.net 1.1
Why does this give this error?
What am I missing here?

Any help will be appreciated.

Thanks
-Siva
 
You will always get null on some rows becasue the control isn't in every row,
for example header rows. If you try to retrieve the control with the
Findcontrol on any rows that don't contain it the it will be set to null so
you will get a run time error if you try to set/get a property or call a
method. The trick is to test to see if it is null first. The below code
will work. and it will work on every line that contains the DDL.

protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
DropDownList ddl =
(DropDownList)e.Row.FindControl("DropDownList1");

if ( ddl != null)
{
ArrayList al = new ArrayList();
al.Add("1");
al.Add("2");
ddl.DataSource = al;
ddl.DataBind();
}

}
}
 
Great. Thanks for the tip. I actually added a line to test if it is a
datarow and only then do a findRow as follows and it works.

if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl =
(DropDownList)e.Row.FindControl("DropDownList1");
......
}
 
Back
Top