2009-03-04 47 views
2

我正在尝试将模板添加到包含Label和TextBox的简化组合控件。我想我的印记,最多是这个样子:我怎样才能有一个ASP.NET模板复合控件?

<test:FormItem ID="fi" runat="server" Title="MyTitle" Text="My Text!"> 
    <TestTemplate> 
     <i> 
      <%# Container.Title) %></i> 
     <br /> 
     <%# Container.Text %> 
    </TestTemplate> 
</test:FormItem> 

我有了对TextBox和标签性能的templateContainer类。

public class TemplateContainer : WebControl, INamingContainer 
{ 

    public TextBox Text { get { return m_item.Text; } } 
    public Label Title { get { return m_item.Title; } } 

    private FormItem m_item; 

    public TemplateContainer(FormItem item) 
    { 
     m_item = item; 
    } 

} 

在主FormItem类我有一个正在从的CreateChildControls(称为CreateControlHierarchy()方法):

protected virtual void CreateControlHierarchy() 
    { 

     m_itemTemplateContainer = new TemplateContainer(this); 
     TestTemplate.InstantiateIn(m_itemTemplateContainer); 

     Controls.Add(m_itemTemplateContainer); 

    } 

我要的是为模板来呈现的实际控制。相反,它在控件上调用ToString()并显示System.Web.UI.WebControls.Label和System.Web.UI.WebControls.TextBox。有没有办法让模板添加控件到它的集合中,而不是只在它们上调用ToString()?

注意:我也尝试将文本框和标签添加到容器的控件集合中,它执行相同的操作。

回答

1

好的。所以我尝试了一些东西,并提出了一个合适的解决方案。

首先,我尝试在数据绑定表达式中使用方法,然后跟踪容器的Control集合中文本框或标签的位置。但是,CompiledTemplateBuilder(这是.Net内部为标记中指定的ITemplates构建的内容)将两个绑定表达式之前和之后的所有标记放入一个DataBoundLiteral控件中,并且在调用该方法时已经创建了Control集合。

做了什么工作就是创建一个新的WebControl,它用作组合控件中控件的占位符。它有一个属性Control,当它被设置时,它将控件添加到它的Controls集合中。

public class FormItemPlaceHolder : WebControl, INamingContainer 
{ 
    public WebControl Control 
    { 
     get 
     { 
      if(Controls.Count == 0) 
       return null; 
      return Controls[0] as WebControl; 
     } 
     set 
     { 
      if (Controls.Count != 0) 
       Controls.Clear(); 
      Controls.Add(value); 
     } 
    } 

} 

然后在标记,创建这种类型的控制,并将其绑定的控件属性,在容器中的正确的属性。

<test:FormItem ID="fi" runat="server" Title="MyTitle" Text="My Text!"> 
    <TestTemplate> 
     <i> 
     <test:FormItemPlaceHolder ID="ph" runat="server" 
      Control='<%# Container.Title %>' /> 
     </i> 
     <br /> 
     <test:FormItemPlaceHolder ID="ph2" runat="server" 
      Control='<%# Container.Text %>' /> 
    </TestTemplate> 
</test:FormItem> 

有没有人有更好的解决方案?

0

容器不应该定义控件,只是数据。

在标记中,您应该定义数据的实际控制,并从容器中为它们分配值。

E.g.

public class TemplateContainer : UserControl 
{ 
    public string Text { get { return m_text; } } 
    public string Title { get { return m_title; } } 

    private string m_text; 
    private string m_title; 
    private FormItem m_item; 

    public TemplateContainer(FormItem item) 
    { 
     m_item = item; 
    } 

} 

而在标记:

<test:FormItem ID="fi" runat="server" Title="MyTitle" Text="My Text!"> 
     <TestTemplate> 
      <i><asp:Label runat="server" Text='<%# Container.Title) %>' /></i> 
      <br /> 
      <asp:TextBox runat="server" Text='<%# Container.Text %>' /> 
    </TestTemplate> 
</test:FormItem> 

如果你想创建一个不需要标记添加控件复合控件,那么你为什么要使用模板?如果只是为了造型,那么创建自己的Style对象可能更有效?

+0

我想创建一个复合控件(控件的控件)并允许用户在控件周围添加标记。注意:我不想创建一个UserControl。我有复合控件中控件的自定义逻辑,我希望它在各种应用程序中使用。 – rmw 2009-04-09 13:36:43