我一直在努力解决一些与在FormView中引用子控件有关的问题。另一位开发人员编写了一个正在编译和工作的ASPX页面,并且在该代码中,他将FormView 中的子控件作为页面对象的属性直接引用。该页面是ASP.NET Web SITE项目的一部分(而不是Web应用程序项目)。我们决定将该项目转换为Web应用程序项目模型,并注意到这些属性引用现在不能编译。文件后面的代码不会在窗体视图中生成控件。ASP.NET根据页面内容编译行为更改?
在研究这个问题时(我在这里有一个关于这些问题的单独帖子),我遇到了一些令人困惑的事情。从我读过的所有文章中,您应该总是使用需要使用FindControl引用FormView模板中的子控件 - 也就是说,无论您是否在Web站点中,都无法通过简单的生成属性进行操作项目模型或Web应用程序项目模型。
我对我的同事的代码编译和运行感到困惑。正如我所指出的,他通过页面中的简单属性来引用FormView包含的子控件,并且不必求助于FindControl调用。为了解开这个谜团的底部,我制作了演示这种现象的最简单的例子。
我发现的东西很奇怪。我在这里的代码有一个ASP:FormView,它的ItemTemplate中有一些标签控件。其中一个标签有ID MyComment。当FormView数据绑定(到Northwind的Products表)时,我只需设置一些文本。
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();
}
}
此代码不会编译,因为MyComment不是有效的属性。这里出现了奇怪的部分。 如果我在FormView的ItemTemplate中嵌入Ajax控件工具包库中的TabContainer控件,上面的代码会编译并正确运行。
所以我的同事的代码编译的原因是因为在FormView内嵌入了TabContainer控件?为什么这应该改变编译器的行为,以及可以访问FormView的子控件的机制对我来说是个谜。顺便说一句,尽管它编译干净并且运行正常,但Intellisense没有看到这些属性,ReSharper将它们报告为编译错误(通过指示条中的红灯)。
这是页面的标记。任何人都可以阐明这种行为?顺便说一下,我并不抱怨ASP.NET在这种情况下创建这些属性的事实。 (不幸的是,如果项目是Web站点项目,这种快乐但奇怪的行为似乎只适用;作为Web应用程序项目,即使使用嵌入式TabControl,属性访问器也不能在FormView中工作)。
<!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>