嵌套服务器控件允许嵌套的html

时间:2009-11-09 05:38:52

标签: html controls nested

有没有人知道如何让嵌套服务器控件接受嵌套的html而不从服务器端“注入”它,即

<uc1:CustomServerControl runat="server">
     <NestedControl></NestedControl>
     <NestedControl2></NestedControl2>
</uc1:CustomServerControl>

但要做到这一点:

<uc1:CustomServerControl runat="server">
    <div>
        <NestedControl>
           <a href="#"></a>
        </NestedControl>
       <NestedControl2></NestedControl2>
    </div>
</uc1:CustomServerControl>

3 个答案:

答案 0 :(得分:1)

试试这个:

Section.cs:

[ToolboxData("<{0}:Section runat=\"server\" />")]
public class Section : WebControl, INamingContainer
{
    private SectionPartCollection _parts;

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
    public SectionPartCollection Parts
    {
        get
        {
            if (this._parts == null)
            {
                this._parts = new SectionPartCollection();
                if (this.IsTrackingViewState)
                    ((IStateManager)this._parts).TrackViewState();
            }
            return this._parts;
        }
    }

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
    public ITemplate LayoutTemplate { get; set; }

    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        if (this.LayoutTemplate != null)
        {
            this.LayoutTemplate.InstantiateIn(this);

            foreach (SectionPart part in this.Parts)
            {
                Control placeHolder = this.FindControl(part.PlaceHolderID);
                if (placeHolder != null)
                    if (part.ContentTemplate != null)
                        part.ContentTemplate.InstantiateIn(placeHolder);
            }
        }
    }

    protected override void LoadViewState(object savedState)
    {
        object[] states = (object[])savedState;

        base.LoadViewState(states[0]);

        if (states[1] != null)
            ((IStateManager)this.Parts).LoadViewState(states[1]);
    }

    protected override object SaveViewState()
    {
        object[] states = new object[2];

        states[0] = base.SaveViewState();

        if (this._parts != null)
            states[1] = ((IStateManager)this.Parts).SaveViewState();

        return states;
    }

    protected override void TrackViewState()
    {
        base.TrackViewState();

        if (this._parts != null)
            ((IStateManager)this._parts).TrackViewState();
    }
}

SectionPart.cs:

[DefaultProperty("PartName")]
public class SectionPart : IStateManager
{
    private StateBag _viewState;
    private bool _isTrackingViewState;

    [DefaultValue("")]
    public string PlaceHolderID
    {
        get { return (string)this.ViewState["PlaceHolderID"] ?? string.Empty; }
        set { this.ViewState["PlaceHolderID"] = value; }
    }

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
    public ITemplate ContentTemplate { get; set; }

    public void SetDirty()
    {
        if (this._viewState != null)
            this.ViewState.SetDirty(true);
    }

    [Browsable(false)]
    protected StateBag ViewState
    {
        get
        {
            if (this._viewState == null)
            {
                this._viewState = new StateBag(false);
                if (this._isTrackingViewState)
                    ((IStateManager)this._viewState).TrackViewState();
            }
            return this._viewState;
        }
    }

    protected virtual bool IsTrackingViewState
    {
        get { return this._isTrackingViewState; }
    }

    protected virtual void LoadViewState(object state)
    {
        if (state != null)
            ((IStateManager)this.ViewState).LoadViewState(state);
    }

    protected virtual object SaveViewState()
    {
        if (this._viewState != null)
            return ((IStateManager)this._viewState).SaveViewState();
        return null;
    }

    protected virtual void TrackViewState()
    {
        this._isTrackingViewState = true;
        if (this._viewState != null)
            ((IStateManager)this._viewState).TrackViewState();
    }

    bool IStateManager.IsTrackingViewState
    {
        get { return this.IsTrackingViewState; }
    }

    void IStateManager.LoadViewState(object state)
    {
        this.LoadViewState(state);
    }

    object IStateManager.SaveViewState()
    {
        return this.SaveViewState();
    }

    void IStateManager.TrackViewState()
    {
        this.TrackViewState();
    }

}

SectionPartCollection.cs:

public class SectionPartCollection : StateManagedCollection
{

    public SectionPart this[int index]
    {
        get { return (SectionPart)((IList)this)[index]; }
    }

    public void Add(SectionPart part)
    {
        if (part == null)
            throw new ArgumentNullException("part");

        ((IList)this).Add(part);
    }

    public void Insert(int index, SectionPart part)
    {
        if (part == null)
            throw new ArgumentNullException("part");

        ((IList)this).Insert(index, part);
    }

    public void Remove(SectionPart part)
    {
        if (part == null)
            throw new ArgumentNullException("part");

        ((IList)this).Remove(part);
    }

    public void RemoveAt(int index)
    {
        ((IList)this).RemoveAt(index);
    }

    protected override void SetDirtyObject(object o)
    {
        ((SectionPart)o).SetDirty();
    }

}

示例:

<uc:Section ID="Section1" runat="server">
    <LayoutTemplate>
        <table>
            <tr>
                <td id="TitlePlaceHolder" runat="server">
                </td>
            </tr>
            <tr>
                <td id="BodyPlaceHolder" runat="server">
                </td>
            </tr>
        </table>
    </LayoutTemplate>
    <Parts>
        <uc:SectionPart PlaceHolderID="TitlePlaceHolder">
            <ContentTemplate>
                <span>Title</span>
            </ContentTemplate>
        </uc:SectionPart>
        <uc:SectionPart PlaceHolderID="BodyPlaceHolder">
            <ContentTemplate>
                <p>
                    Some content...</p>
            </ContentTemplate>
        </uc:SectionPart>
    </Parts>
</uc:Section>

答案 1 :(得分:0)

试试这个:

[ToolboxData("..."), ParseChildren(false), PersistChildren(true)]
public class CustomServerControl : WebControl, INamingContainer
{
}

答案 2 :(得分:0)

这个基本的目的是拥有一个自定义Generic标记库,在这种情况下,它将与底层对象模型对话。对象模型负责将文章分成各自的部分,即标题,模糊,图像,评论等。在这种情况下,我正在考虑它们的集合,并通过指定内部标记,您基本上应用过滤器到你希望看到的部分文章的哪些部分。

   <uc1:Section runat="server">     
     <HeadLine></HeadLine>     
     <Blurb></Blurb>     
     <Body></Body>
   </uc1:Section>

根据用户仅通过标记他需要的内容指定的内容,相应的内容将被写入前端。

现在这个效果非常好,除了在一两个案例中你实际上需要某种内部结构到文章的每个部分,然后将它投射到整个集合上,就像有一个{{1}标题应该放在一个<table>中,其余的放到另一个<td>

希望它有意义!!