C# 自定义用户控件中的ASP嵌套标记

C# 自定义用户控件中的ASP嵌套标记,c#,.net,asp.net,custom-server-controls,C#,.net,Asp.net,Custom Server Controls,我刚刚开始使用C#中的自定义用户控件,我想知道是否有任何示例说明如何编写一个接受嵌套标记的控件 例如,当您创建一个asp:repeater时,您可以为itemtemplate添加一个嵌套标记。简而言之,如果控件具有以下标记: <Abc:CustomControlUno runat="server" ID="Control1"> <Children> <Abc:Control1Child IntegerProperty="1" />

我刚刚开始使用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; }
}
[ParseChildren(true)]
[儿童(对)]
[ToolboxData(“”)
公共类CustomControlUno:WebControl,INamingContainer
{
私人控制1儿童收藏(U儿童);;
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
公共控制1儿童收集儿童
{
得到
{
if(_children==null)
{
_children=新控件1childrencollection();
}
返回儿童;
}
}
}
公共类控件1儿童集合:列表
{
}
公共班级控制1儿童
{
公共整数整型属性{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>

我最终得到的答案与(in)的答案非常相似,但我使用了
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>
重要位(?):

  • ParseChildren
    ——那么东西呢
  • PersistChildren
    ——那么动态创建的内容不会被重置
  • PersistenceMode(PersistenceMode.InnerProperty)
    ——因此控件
  • DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
    ——同上
控件的使用

底部的东西!(不再是空的)

如果它回答了这个问题,就不要认为它的形式很糟糕。当人们只写博文的时候。那就是疯狂制造的时候。点击一下,谢谢!非常感谢。非常感谢。哇,这已经在这里站了三年多了,一直以来,我都被过于复杂和复杂的“例子”打到脸上,而这些“例子”根本不起作用。非常感谢。链接博客帖子的问题是当网站死掉时。我打字的时候是这样的。因此我看不到答案。@tjmoore我同意——试着在上面查找
<!-- 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>
[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);
    }
}
<%@ 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>