Voici ce que je veux:contrôles enfants ASP.NET WebControl ITemplate sont nuls
Je veux un contrôle à mettre sur une page, que d'autres développeurs peuvent placer des éléments de forme à l'intérieur de pour afficher les entités que mon contrôle est à la recherche . J'ai la logique de recherche tout fonctionne. Le contrôle crée des champs de recherche personnalisés et effectue des recherches basées sur des classes C# déclaratives mettant en œuvre mon interface SearchSpec
.
Voici ce que j'ai essayé:
J'ai essayé d'utiliser ITemplate sur un WebControl qui implémente INamingContainer J'ai essayé mettre en œuvre un CompositeControl
Le plus proche que je peux obtenir de travail est inférieure à .
OK J'ai une coutume 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;
}
}
alors l'utilisation:
<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>
Le problème est que dans le CodeBehind, la page a des membres descriptionBox, ownerBox et testNameBox. Cependant, ils sont tous nuls. En outre, FindControl("ownerBox")
renvoie null comme le fait this.sp1.FindControl("ownerBox")
. Je dois faire this.sp1.MyTemplateContainer.FindControl("ownerBox")
pour obtenir le contrôle.
Comment puis-je faire en sorte que le code C# Derrière aura les commandes générées et non nulle dans mon cas Page_Load afin que les développeurs peuvent tout faire:
testNameBox.Text = "foo";
ownerBox.Text = "bar";
descriptionBox.Text = "baz";