ASP.NET: пользовательский элемент управления с доступом к элементам управления, которые он упаковывает - PullRequest
1 голос
/ 30 октября 2009

В моем проекте 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>

Как вы уже догадались, все в этом фрагменте - чистый шаблон, кроме самого внутреннего текстового поля.

Каков наилучший способ избежать такого шаблонного в ASP.NET? Например, Django Я бы сделал для него специальный тэг:

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

Я думал, что, возможно, я смогу создать пользовательский элемент управления, но все учебники по пользовательским элементам управления ASP.NET, которые я обнаружил, очень упрощены и «самозакрывающиеся», то есть они не знают содержимого тег. Мне нужно что-то вроде:

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

Итак, мой вопрос заключается в следующем: как лучше всего избежать этого?

Ответы [ 3 ]

2 голосов
/ 30 октября 2009

Вы можете использовать свойство 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();
    }
}
0 голосов
/ 05 ноября 2009

Создайте такой класс:

[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 и т. Д.

0 голосов
/ 30 октября 2009

Поместите asp: TextBox в свой пользовательский элемент управления вместе с другими тегами html. Укажите в вашем пользовательском элементе свойства, соответствующие свойствам текстового поля, чтобы вы могли сделать что-то вроде этого:

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

и тогда свойства width и maxlength просто будут переданы во внутреннее текстовое поле.

Вы также можете предоставить доступ к текстовому полю из usercontrol и установить все свойства в коде.

...