2008-12-10 43 views
0

我一直在努力解决一些与在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> 

回答

0

当您转换网页网站到Web应用程序,你检查的部分类为您的aspx文件被正确生成(如应该有一个叫“Default.aspx.cs文件.designer“,在您的Web应用程序的Default.aspx和Default.aspx.cs文件下)。

在Web 网站,这些都是由服务器动态生成的网站上运行,并且编译(所以不要在你的项目中存在),而在Web应用程序他们创建和由Visual Studio管理 - 如果它们不存在,则代码可能无法编译,因为对象没有被安装 - 您看到的实际编译器错误是什么?

在将项目转换为Web应用程序后,通过向页面添加一个新控件,迫使VS创建缺少的部分类。

0

Zhaph,

谢谢您的回复。是的,设计师档案在那里。我想我的问题太多了,并且把问题搞糊涂了。令人费解的行为在Web SITE项目中得到证明。

底线是,在FormView中的属性将无法编译除非在FormView中有一个中间TabContainer控件。如果TabContainer在那里,那么属性就会编译和工作。如果从FormView中删除TabContainer,代码将不会编译。很奇怪。到目前为止,没有人能解释这一点。