From: Howard Pinsley on
I've been struggling with some issues relating to referencing child controls
within a FormView. Another developer wrote an ASPX page that is compiling
and working and in that code, he references child controls within a FormView
**directly** as properties of the page object. The page is part of an
ASP.NET Web SITE Project (as opposed to a Web Application Project). We
decided to convert the project to the Web Application Project model and
noticed that these property references now don't compile. The code behind
file does not generate the controls within the form view.

While researching that issue (I had a separate post here regarding those
problems), I came across something baffling. From all the posts I've read,
you should **always** need to reference child controls within a FormView's
template using FindControl -- i.e. it is supposedly not possible to do
through a simple generated property regardless of whether you're in the Web
Site Project model or the Web Application Project model.

I was puzzled as to how my colleague's code compiled and ran. As I
indicated, he is referencing the FormView's contained child controls through
simple properties in the page and did not have to resort to FindControl
calls. So to get to the bottom of this mystery, I cooked up the shortest
example that demonstrates this phenomenon.

What I found was very strange. The code I have here has a ASP:FormView with
a few label controls within it's ItemTemplate. One of those labels has the
ID **MyComment**. When the FormView databinds (to the Northwind's Products
table), I simply set some text.

using System;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.FormView1.ChangeMode(FormViewMode.ReadOnly);
}
protected void FormView1_DataBound(object sender, EventArgs e) {
MyComment.Text = "Data bound at " + DateTime.Now.ToString();
}
}

This code will not compile because MyComment is not a valid property. Here
comes the strange part. **If I embed within the FormView's ItemTemplate a
TabContainer control from the Ajax Control Toolkit library, the code above
does compile and runs correctly**.

So the reason my colleague's code is compiling is because of the embedded
TabContainer control within the FormView?? Why this should change the
behavior of the compiler and the mechanisms by which you can get access to
the FormView's child controls is a mystery to me. Incidentally, despite the
fact that it compiles cleanly and runs correctly, Intellisense does not see
these properties and ReSharper reports them as compile errors (by the red
light in the indicator bar).

Here is the markup for the page. Can anyone shed some light on this
behavior? Incidentally, I'm not complaining about the fact that ASP.NET
creates these properties in this circumstance. (Unfortunately, this happy,
but strange, behavior, only seems to apply if the project is a Web Site
Project; as a Web Application Project, property accessors don't work within
the FormView even with the embedded TabControl).


<!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></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:FormView ID="FormView1" runat="server"
DataKeyNames="ProductID" DataSourceID="SqlDataSource1"
OnDataBound="FormView1_DataBound">
<ItemTemplate>
<ajaxToolkit:TabContainer runat="server" ID="TabsItem">
<ajaxToolkit:TabPanel runat="Server"
ID="PanelBasicsItem" HeaderText="Basics">
<ContentTemplate>
ProductID:
<asp:Label ID="ProductIDLabel"
runat="server" Text='<%# Eval("ProductID") %>' />
<br />
ProductName:
<asp:Label ID="ProductNameLabel"
runat="server" Text='<%# Bind("ProductName") %>' />
<br />
My Comment:
<asp:Label ID="MyComment"
runat="server"></asp:Label>
<br />
</ContentTemplate>
</ajaxToolkit:TabPanel>
</ajaxToolkit:TabContainer>
</ItemTemplate>
</asp:FormView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName] FROM
[Alphabetical list of products]">
</asp:SqlDataSource>
</div>
</form>
</body>
</html>