У меня получилось нечто очень похожее на ответ Роб (в Архив обратного хода ) @ gudmundur-h , но я использовал ITemplate
избавиться от этого раздражающего "Вы не можете размещать контент между тегами X" в использовании. Я не совсем уверен, что на самом деле требуется или нет, так что все на всякий случай.
Частичная / пользовательская разметка управления: mycontrol.ascx
Обратите внимание на важные биты: plcChild1
и plcChild2
.
<!-- markup, controls, etc -->
<div class="shell">
<!-- etc -->
<!-- optional content with default, will map to `ChildContentOne` -->
<asp:PlaceHolder ID="plcChild1" runat="server">
Some default content in the first child.
Will show this unless overwritten.
Include HTML, controls, whatever.
</asp:PlaceHolder>
<!-- etc -->
<!-- optional content, no default, will map to `ChildContentTwo` -->
<asp:PlaceHolder ID="plcChild2" runat="server"></asp:PlaceHolder>
</div>
Код частичного / пользовательского контроля: mycontrol.ascx.cs
[ParseChildren(true), PersistChildren(true)]
[ToolboxData(false /* don't care about drag-n-drop */)]
public partial class MyControlWithNestedContent: System.Web.UI.UserControl, INamingContainer {
// expose properties as attributes, etc
/// <summary>
/// "attach" template to child controls
/// </summary>
/// <param name="template">the exposed markup "property"</param>
/// <param name="control">the actual rendered control</param>
protected virtual void attachContent(ITemplate template, Control control) {
if(null != template) template.InstantiateIn(control);
}
[PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public virtual ITemplate ChildContentOne { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public virtual ITemplate ChildContentTwo { get; set; }
protected override void CreateChildControls() {
// clear stuff, other setup, etc
// needed?
base.CreateChildControls();
this.EnsureChildControls(); // cuz...we want them?
// using the templates, set up the appropriate child controls
attachContent(this.ChildContentOne, this.plcChild1);
attachContent(this.ChildContentTwo, this.plcChild2);
}
}
Важные биты (?):
ParseChildren
- так выглядит ?
PersistChildren
- так что динамически создаваемый материал не сбрасывается?
PersistenceMode(PersistenceMode.InnerProperty)
- поэтому элементы управления анализируются правильно
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
- то же самое?
Контроль использования
<%@ Register Src="~/App_Controls/MyStuff/mycontrol.ascx" TagPrefix="me" TagName="MyNestedControl" %>
<me:MyNestedControl SomeProperty="foo" SomethingElse="bar" runat="server" ID="meWhatever">
<%-- omit `ChildContentOne` to use default --%>
<ChildContentTwo>Stuff at the bottom! (not empty anymore)</ChildContentTwo>
</me:MyNestedControl>