ASP.NET WebControl ITemplate дочерние элементы управления являются нулевыми - PullRequest
1 голос
/ 17 апреля 2010

Вот что я хочу:

Я хочу разместить элемент управления на странице, чтобы другие разработчики могли размещать внутри него элементы формы для отображения сущностей, которые ищет мой элемент управления. У меня логика поиска все работает. Элемент управления создает пользовательские поля поиска и выполняет поиск на основе декларативных классов C #, реализующих мой интерфейс SearchSpec.

Вот что я пытался:

Я пытался использовать ITemplate в WebControl, который реализует INamingContainer. Я пытался реализовать CompositeControl

Самое близкое, что я могу получить к работе - это ниже.

ОК. У меня есть собственный WebControl

[
AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
DefaultProperty("SearchSpecName"),
ParseChildren(true),
ToolboxData("<{0}:SearchPage runat=\"server\"> </{0}:SearchPage>")
]
public class SearchPage : WebControl, INamingContainer
{

    [Browsable(false),
    PersistenceMode(PersistenceMode.InnerProperty),
    DefaultValue(typeof(ITemplate), ""),
    Description("Form template"),
    TemplateInstance(TemplateInstance.Single),
    TemplateContainer(typeof(FormContainer))]
    public ITemplate FormTemplate { get; set; }

    public class FormContainer : Control, INamingContainer{ }

    public Control MyTemplateContainer { get; private set; }

    [Bindable(true), Category("Behavior"), DefaultValue(""),
     Description("The class name of the SearchSpec to use."), Localizable(false)]
    public virtual string SearchSpecName
    {
        get;
        set;
    }

    [Bindable(true), Category("Behavior"), DefaultValue(true), 
    Description("True if this is query mode."), Localizable(false)]
    public virtual bool QueryMode
    {
        get;
        set;
    }

    private SearchSpec _spec;
    private SearchSpec Spec
    {
        get
        {
            if (_spec == null)
            {
                Type type = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.Name == SearchSpecName).First();
                _spec = (SearchSpec)Assembly.GetExecutingAssembly().CreateInstance(type.Namespace + "." + type.Name);
            }
            return _spec;
        }
    }

    protected override void CreateChildControls()
    {
        if (FormTemplate != null)
        {
            MyTemplateContainer = new FormTemplateContainer(this);
            FormTemplate.InstantiateIn(MyTemplateContainer);
            Controls.Add(MyTemplateContainer);
        }
        else
        {
            Controls.Add(new LiteralControl("blah"));
        }

    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
        // <snip>
    }


    protected override HtmlTextWriterTag TagKey
    {
        get
        {
            return HtmlTextWriterTag.Div;
        }
    }

}

public class FormTemplateContainer : Control, INamingContainer
{
    private SearchPage parent;
    public FormTemplateContainer(SearchPage parent)
    {
        this.parent = parent;
    }
}

тогда использование:

<tster:SearchPage ID="sp1" runat="server" SearchSpecName="TestSearchSpec" QueryMode="False">
 <FormTemplate>
    <br />
    Test Name:
    <asp:TextBox ID="testNameBox" runat="server" Width="432px"></asp:TextBox>
    <br />
    Owner:
    <asp:TextBox ID="ownerBox" runat="server" Width="427px"></asp:TextBox>
    <br />
    Description:
    <asp:TextBox ID="descriptionBox" runat="server" Height="123px" Width="432px" 
        TextMode="MultiLine" Wrap="true"></asp:TextBox>
 </FormTemplate>
</tster:SearchPage>

Проблема в том, что в CodeBehind на странице есть элементы descriptionBox, ownerBox и testNameBox. Тем не менее, они все нулевые. Кроме того, FindControl("ownerBox") возвращает ноль, как и this.sp1.FindControl("ownerBox"). Я должен сделать this.sp1.MyTemplateContainer.FindControl("ownerBox"), чтобы получить контроль.

Как я могу сделать так, чтобы в коде C # Behind были сгенерированы элементы управления, а не нуль в моем событии Page_Load, чтобы разработчики могли просто сделать это:

testNameBox.Text = "foo";
ownerBox.Text = "bar";
descriptionBox.Text = "baz";

1 Ответ

0 голосов
/ 18 апреля 2010

ОК, я исправил это, заставив SearchPage расширить Panel и удалив ParseChildren (true).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...