【问题标题】:ASP.NET: User control with access to the controls that it wrapsASP.NET:可以访问它包装的控件的用户控件
【发布时间】:2009-10-30 15:33:29
【问题描述】:

在我的 ASP.NET 项目中出现了很多此类样板代码。

<div class="inputfield">
  <div class="tl">
    <span class="tr"><!-- --></span>
    <span class="ll"><!-- --></span>
    <div class="lr">
      <div class="cntnt">
        <asp:TextBox .../>
      </div>
    </div>
  </div>
</div>

您可能已经猜到了,除了最里面的文本字段之外,该 sn-p 中的所有内容都是纯样板文件。

在 ASP.NET 中避免此类样板的最佳方法是什么?在例如Django 我会为它制作一个自定义标签,如下所示:

{% boiler %}
<input ... />
{% endboiler %}

我在想也许我可以创建一个用户控件,但是我发现的所有关于 ASP.NET 用户控件的教程都非常简单和“自动关闭”,即他们不知道标签。我需要一些类似的东西:

<Hello:MyControl>
  <asp:TextBox .../>
</Hello>

所以我的问题是:避免样板文件的最佳方法是什么?

【问题讨论】:

    标签: asp.net user-controls boilerplate


    【解决方案1】:

    您可以使用 ITemplate 属性。因此,您可以在不同的情况下注入不同的内容。

    [PersistChildren(false), ParseChildren(true, "ContentTemplate")]
    public partial class WebUserControl1 : System.Web.UI.UserControl
    {
    
        [System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ContentTemplate { get; set; }
    
        protected override void CreateChildControls()
        {
            if (this.ContentTemplate != null)
                this.ContentTemplate.InstantiateIn(this);
    
            base.CreateChildControls();
        }
    }
    

    【讨论】:

    • 对不起,我真的不明白如何使用这个代码sn-p。在这种情况下,.ascx 文件是什么样的?
    • 我想我现在明白了,但还有一个问题......如果我不想使用 ContentTemplate 或类似的东西怎么办?
    【解决方案2】:

    将 asp:TextBox 与其他 html 标记一起放入您的用户控件中。在您的用户控件上提供与文本框的属性相匹配的属性,以便您执行以下操作:

    <Hello:MyControl ID="myControl" runat="server" Width="300px" MaxLength="30" />
    

    然后 width 和 maxlength 属性将被转移到内部文本框。

    您还可以从用户控件提供对文本框的访问权限,并在后面的代码中设置所有属性。

    【讨论】:

    • 这还不够,因为应该可以将任何内容放入控件中,而不仅仅是文本框。
    • 啊 - 抱歉,我错过了问题的那一部分。
    • 我现在意识到我应该在这方面更清楚! :)
    【解决方案3】:

    像这样创建一个类:

    [PersistChildren(false), ParseChildren(true, "ContentTemplate")]
    public class CustomContent:WebControl
    {
        [System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public ITemplate ContentTemplate { get; set; }
    
        private PlaceHolder m_placeHolder;
        protected override void CreateChildControls()
        {
            m_placeHolder = new PlaceHolder();
    
            if (this.ContentTemplate != null)
                this.ContentTemplate.InstantiateIn(m_placeHolder);
    
            Controls.Add(m_placeHolder);
        }
    
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write(@"<div class=""inputfield"">
    <div class=""tl"">
    <span class=""tr""><!-- --></span>
    <span class=""ll""><!-- --></span>
    <div class=""lr"">
      <div class=""cntnt"">
    ");
            base.RenderContents(writer);
    
            writer.Write(@"      </div>
    </div>
    </div>
    </div>
    ");
        }
    
    }
    

    此类不是“用户控件”,而是“服务器控件”。你可以对用户控件做同样的事情,但你会遇到设计器的问题。这将在设计器中工作。 您可以在 ASPX 中添加这样的标记:

        <uc1:CustomContent runat="server" ID="content">
           <asp:textbox runat="server"></asp:textbox>
        </uc1:CustomContent>
    

    不要忘记 aspx 顶部的注册页面声明

    <%@ Register tagprefix="uc1" Assembly="Assembly where CustomContent is" Namespace="namespace where CustomContent is" %>
    

    您可以在 uc1:CustomContent 标记中放置您想要的任何内容,它会在其周围呈现该样板 html。如果您对 ITemplate 的工作原理感到好奇,msdn 等上有很多文章。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-15
      • 2013-11-09
      相关资源
      最近更新 更多