0

Does anyone know how to make nested server controls accept nested html without "injecting" it out from serverside, ie.

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

but to do this:

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

3 Answers 3

1

Try this:

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();
    }

}

Example:

<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>
Sign up to request clarification or add additional context in comments.

1 Comment

You gave me some ideas, I'll come back to you once implemented
0

Try this:

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

2 Comments

My problem is that I have to set ParseChildren(true), as the main servercontrol contains nested controls that needs to be rendered, I need to combine the functionality of treating the control children as properties and render html.
I think, it's not possible exactly. As you demonstared in the second code snippet, you put an CustomServerControl properties onto the inner HTML of a div which the server control can not parse them. I don't know what you want to do and why? If you explain the ServerControl task, maybe I can help.
0

The purpose of this basicly is to have a custom Generic tag library, whick in this case will speak to a underlying object model. The objectmodel is responsible for splitting up articles into its respective parts, ie, Headline, blurb, Images, Comments etc. In this case I'm woring with a collection of them, and by specifying the inner tags, you basicly apply a filter onto what parts of the articles in the section you want to see.

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

Based on what the user specify by only tagging whatever he needs, the respective content will then be written to the frontend.

Now this works wonderfully well, except in one or two cases where you actually need some kind of internal structure to each of the individual parts of an article, and then projecting that onto the entire collection, like having a <table> where the headline should go into one <td> and the rest into another <td>

Hope it makes sense!!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.