Как я могу иметь шаблонный элемент управления ASP.NET? - PullRequest
2 голосов
/ 04 марта 2009

Я пытаюсь добавить шаблон в упрощенный составной элемент управления, содержащий метку и текстовое поле. Я хочу, чтобы моя пометка выглядела примерно так:

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

У меня есть класс templateContainer, который имеет свойства для TextBox и Label.

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 у меня есть метод CreateControlHierarchy (), который вызывается из CreateChildControls ():

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 () для них?

Примечание. Я также попытался добавить текстовое поле и метку в коллекцию элементов управления контейнера, которая делает то же самое.

Ответы [ 2 ]

1 голос
/ 05 марта 2009

Хорошо. Поэтому я попробовал несколько вещей и нашел правильное решение.

Сначала я попытался использовать методы в выражении привязки данных, а затем отслеживал, куда в коллекции 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);
        }
    }

}

Затем в разметке я создаю элемент управления этого типа и связываю его свойство Control с правильным свойством в контейнере.

<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 голосов
/ 11 марта 2009

Контейнер не должен определять элементы управления, только данные.

Именно в разметке вы должны определить фактические элементы управления данными и присвоить им значения из контейнера.

* 1005 Е.Г. *

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 может быть более эффективным?

...