我刚刚开始使用 C# 中的自定义用户控件,我想知道是否有任何示例说明如何编写一个接受嵌套标签的示例?
例如,当您创建一个时,asp:repeater
您可以为itemtemplate
.
我刚刚开始使用 C# 中的自定义用户控件,我想知道是否有任何示例说明如何编写一个接受嵌套标签的示例?
例如,当您创建一个时,asp:repeater
您可以为itemtemplate
.
前段时间我写了一篇关于这个的博客文章。简而言之,如果您有一个带有以下标记的控件:
<Abc:CustomControlUno runat="server" ID="Control1">
<Children>
<Abc:Control1Child IntegerProperty="1" />
</Children>
</Abc:CustomControlUno>
您需要控件中的代码符合以下要求:
[ParseChildren(true)]
[PersistChildren(true)]
[ToolboxData("<{0}:CustomControlUno runat=server></{0}:CustomControlUno>")]
public class CustomControlUno : WebControl, INamingContainer
{
private Control1ChildrenCollection _children;
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Control1ChildrenCollection Children
{
get
{
if (_children == null)
{
_children = new Control1ChildrenCollection();
}
return _children;
}
}
}
public class Control1ChildrenCollection : List<Control1Child>
{
}
public class Control1Child
{
public int IntegerProperty { get; set; }
}
我按照 Rob 的博客文章,做了一个稍微不同的控制。该控件是一个有条件的控件,实际上就像一个 if 子句:
<wc:PriceInfo runat="server" ID="PriceInfo">
<IfDiscount>
You don't have a discount.
</IfDiscount>
<IfNotDiscount>
Lucky you, <b>you have a discount!</b>
</IfNotDiscount>
</wc:PriceInfo>
然后,在代码中,我HasDiscount
将控件的属性设置为布尔值,它决定呈现哪个子句。
与 Rob 的解决方案的最大区别在于,控件中的子句确实可以包含任意 HTML/ASPX 代码。
这是控件的代码:
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebUtilities
{
[ToolboxData("<{0}:PriceInfo runat=server></{0}:PriceInfo>")]
public class PriceInfo : WebControl, INamingContainer
{
private readonly Control ifDiscountControl = new Control();
private readonly Control ifNotDiscountControl = new Control();
public bool HasDiscount { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Control IfDiscount
{
get { return ifDiscountControl; }
}
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Control IfNotDiscount
{
get { return ifNotDiscountControl; }
}
public override void RenderControl(HtmlTextWriter writer)
{
if (HasDiscount)
ifDiscountControl.RenderControl(writer);
else
ifNotDiscountControl.RenderControl(writer);
}
}
}
我最终得到了与Rob(在Wayback存档中)@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>
我猜你正在寻找这样的东西?http://msdn.microsoft.com/en-us/library/aa478964.aspx
您的标签已被删除或不可见,因此无法真正帮助您。