Adding controls to EditableDesignerRegion/ITemplate in code.

Discussion in 'ASP .Net Building Controls' started by Christophe Peillet, Apr 4, 2006.

  1. I have a base custom control called 'WebBox' that contains a single
    EditableDesignerRegion. The contents of this EditableDesignerRegion are
    stored in an ITemplate via a property name 'Content', and serialized as an
    InnerProperty.

    This all works as expected, renders properly, etc., but I can't figure out
    how, in a control that inherits WebBox (such as AdvertisementWebBox,
    SearchWebBox, etc.) to add controls to the ITemplate in code on the Server
    Side. If I add things in the markup, as below, everything works fine (see
    inner property names 'Content').

    <CompanyUI:WebBox ID="SearchWebBox" runat="server" IconWidth="0"
    SkinID="SearchBox"
    Title="Search" TitleVisible="True" Width="180px">
    <Content>
    <div style="text-align: center">
    <table border="0" cellpadding="0" cellspacing="0"
    style="width: 100%">
    <tr>
    <td align="left" style="width: 130px" valign="top">
    <CompanyUI:AdvancedTextBox ID="AdvancedTextBox1"
    runat="server" LabelPosition="Bottom"

    Width="130px"></CompanyUI:AdvancedTextBox></td>
    <td align="center" valign="top">
    <CompanyUI:AdvancedButton ID="SearchButton"
    runat="server" Text="go" /></td>
    </tr>
    <tr>
    <td align="left" colspan="2" style="width: 130px"
    valign="top">
    <CompanyUI:CompanyHyperLink
    ID="AdvancedSearchLink" runat="server" Description="" LinkLeaderCssClass=""
    LinkLeaderImageCssClass=""
    LinkLeaderImageUrl="" NavigateUrl="~/AdvancedSearch.aspx"
    TextResourceKey="AdvancedSearch">Advanced
    Search</CompanyUI:CompanyHyperLink></td>
    </tr>
    </table>
    </div>
    </Content>
    </CompanyUI:WebBox>

    How can I do this in code in another specialized server control, though?

    In the server control that inherits WebBox, I have tried the following, but
    with no success.

    protected override void OnPreRender(EventArgs e)
    {
    // Call underlying OnPreRender method
    base.OnPreRender(e);

    if (!(this.DesignMode))
    {
    // Clear WebBox .Content control collection
    Control template = new Control();
    base.Content.InstantiateIn(template);

    // ToDo: How to add controls to an ITemplate in code?

    template.Controls.Clear();

    ... // Add controls to collection
    ... template.Controls.Add(...) ...
    }
    }

    I want WebBox as a generic control with an empty ITemplate, and in
    specialized controls that inherit from it to add controls like Search boxes,
    link listings, etc.

    Any help on this would be appreciated.
    Christophe Peillet, Apr 4, 2006
    #1
    1. Advertising

  2. Thank you for posting,

    As for the Template based control in ASP.NET, the template property
    (ITemplate) can not be created like normal control(by adding new controls
    into Controls collection). If we want to dynamically populate an template
    and use it in any Template based control, we need to create a custom
    Template class and add our custom code logic in the Template's code. Here
    are the msdn reference described programmatically creating ASP.NET server
    control template:

    #Creating Web Server Control Templates Dynamically
    http://msdn.microsoft.com/library/en-us/vbcon/html/vbtskcreatingwebservercon
    troltemplatesdynamically.asp?frame=true

    #Creating Templates Programmatically in the DataGrid Control
    http://msdn.microsoft.com/library/en-us/vbcon/html/vbtskcreatingtemplatespro
    grammaticallyindatagridcontrol.asp?frame=true

    Hope this helps.

    Regards,

    Steven Cheng
    Microsoft Online Community Support


    ==================================================

    When responding to posts, please "Reply to Group" via your newsreader so
    that others may learn and benefit from your issue.

    ==================================================


    This posting is provided "AS IS" with no warranties, and confers no rights.



    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
    Steven Cheng[MSFT], Apr 4, 2006
    #2
    1. Advertising

  3. After looking at these examples, I'm still a bit lost. I have made a class
    that implements ITemplate, but still do not see how I can get access to
    something similar to a ControlCollection to add objects inside the template
    at run time. The ITemplate class is included below.

    The example you gave me has a bit of code in the InstantiateIn method (using
    a switch), but I don't see how this is relevant to my needs. I only have one
    template, and simply need to be able to insert (via code) any controls into
    it, via something like 'MyServerControl.Content.Controls.Add(x);' when
    ..Content is the ITemplate (or, in this case, 'WebBoxTemplate'). Sorry to
    bother you with this again, but if you know something a bit closer to my
    situation it would help me a lot.

    As always, thanks for your help,

    using System;
    using System.IO;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Globalization;
    using System.Drawing.Design;
    using System.Diagnostics;
    using System.Reflection;
    using CompanyName.EEE.Web.UI;
    using CompanyName.EEE.Web.UI.FormControls;

    namespace CompanyName.EEE.Web.UI.WebBoxes
    {
    /// <summary>
    /// This class provides an implementation of the <see cref="T:ITemplate"
    />
    /// interface for allowing access to the <see cref="T:ITemplate" /> and
    /// <see cref="T:EditableDesignerRegion" /> properties/methods in
    /// <see cref="T:WebBox" /> controls.
    /// </summary>
    public class WebBoxTemplate : ITemplate
    {
    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="WebBoxTemplate"/>
    class.
    /// </summary>
    public WebBoxTemplate()
    {
    }

    #endregion

    #region Public Methods

    /// <summary>
    /// When implemented by a class, defines the <see cref="T:Control"
    /> object
    /// that child controls and templates belong to. These child
    controls are
    /// in turn defined within an inline template.
    /// </summary>
    /// <param name="container">The <see cref="T:Control" /> object to
    contain
    /// the instances of controls from the inline template.</param>
    public void InstantiateIn(Control container)
    {
    // How to pass something at run-time to container.Controls ?
    }

    #endregion

    }
    }
    Christophe Peillet, Apr 4, 2006
    #3
  4. Thanks for your response,

    Yes, I know your confusion. Actually, what I used to think is that you want
    to do what we do at design-time( add some controls into Template by editing
    the Templte's inline markup in aspx file). As for ASP.NET control
    template, at design-time it is persisted as markup string, at runtime, the
    ASP.NET will call the template's InInstantiateIn method which will parse
    and compile the template and build the template's control collection. Then,
    those controls will be add into a container control's controls collection.

    So one means to dynamically add additional controls into Template is define
    custom template class, and we can completely programmatically create the
    template at runtime and assign it to our custom control's Template field.

    Also, another means is do something on the Container control, just like the
    "ItemDataBound" or "RowDataBound" event of the DataGrid , GridView
    control. Generally after calling template's InInstantiateIn, we'll add the
    returned controls into a container control(such as the DataGridItem of
    DataGrid). So in your custom control, you can consider use such a container
    control to do the dynamic control adding or modifying.

    Regards,

    Steven Cheng
    Microsoft Online Community Support


    ==================================================

    When responding to posts, please "Reply to Group" via your newsreader so
    that others may learn and benefit from your issue.

    ==================================================


    This posting is provided "AS IS" with no warranties, and confers no rights.



    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
    Steven Cheng[MSFT], Apr 5, 2006
    #4
  5. Steven:

    I understood the need to override the InstantiateIn method ... what I
    couldn't figure out is what code to put to be able to pass any number of
    controls to this method at run time.

    Would something like this work (I don't have VS in front of me to know the
    exact signature of this method):

    protected override void (?) InstantiateIn(ControlCollection controlsToAdd)
    {
    ...
    // And then add the contents of the passed ControlCollection into the
    container?
    }

    My problem was handing the controls over to the InstantiateIn method ... I
    just didn't see a good way to do this. If I can, I would like to avoid other
    developers using my APIs or Framework from having to write 5 lines of code to
    add a control to my ITemplate based property. Do you have any ideas or code
    suggestions on how to do this in the InstantiateIn method?

    As always, I appreciate your help and expertise on this.

    Christophe
    Christophe Peillet, Apr 8, 2006
    #5
  6. Thanks for your response Christophe,

    I haven't found any particular resource on write our custom Template class
    (override the InstantiateIn method). Also, I think you can consider the
    other approach I mentioned, create a container class which hold the
    controls intialized from the Template and we can throw some event (which
    contains eventARgument reference to that container) so that the control's
    user can use that event to customize the controls collection intialized
    from Template. And in those ASP.NET built-in controls, you can have a look
    at the Repeater control(also DataList) which use a container control (e.g
    the Repeater's RepeaterItem ....). You can use the reflector tool to
    inspect into its code, you'll find it create a RepeaterItem through the
    CreateItem function and then call initializeItem which internally call the
    template.InstantiateIn to parse the template controls, then raise some
    events to let the user to customize the controls collection.

    here is the reference code from reflector:

    ===========================
    private RepeaterItem CreateItem(int itemIndex, ListItemType itemType, bool
    dataBind, object dataItem)
    {
    RepeaterItem item1 = this.CreateItem(itemIndex, itemType);
    RepeaterItemEventArgs args1 = new RepeaterItemEventArgs(item1);
    this.InitializeItem(item1);
    if (dataBind)
    {
    item1.DataItem = dataItem;
    }
    this.OnItemCreated(args1);
    this.Controls.Add(item1);
    if (dataBind)
    {
    item1.DataBind();
    this.OnItemDataBound(args1);
    item1.DataItem = null;
    }
    return item1;
    }
    ============================

    Hope this helps.

    Regards,

    Steven Cheng
    Microsoft Online Community Support


    ==================================================

    When responding to posts, please "Reply to Group" via your newsreader so
    that others may learn and benefit from your issue.

    ==================================================


    This posting is provided "AS IS" with no warranties, and confers no rights.



    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
    Steven Cheng[MSFT], Apr 10, 2006
    #6
  7. hi Christophe, Have you tried to add the information via the ToolboxData
    Metadata attributes since these are applied to server controls (and to their
    members) to provide information that is used by design tools, the ASP.NET
    page parser, the ASP.NET run time, and the common language runtime.
    Something like the following should work well for you :

    [ToolboxData("<{0}:WebBox runat=\"server\">" +
    "<Content>" +
    " <div style=\"text-align: center\">" +
    "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"
    style=\"width: 100%\">" +
    "<tr>" +
    "<td> <CompanyUI:AdvancedTextBox ID=\"AdvancedTextBox1\"
    runat=\"server\" LabelPosition=\"Bottom\"
    Width=\"130px\"></CompanyUI:AdvancedTextBox></td>" +
    "</tr>" +
    "</table>" +
    "</div>" +
    "</Content>" +
    "</{0}:WebBox>"),
    Designer(typeof(SimpleContainerControlDesigner))]
    public class WebBox : CompositeControl
    {//definition for your webbox control}

    When this control gets dropped in the page, the string passed to the
    MetaData attribute ToolboxData is rendered into the page as as part of your
    control, just as you want it. Atleast it seems to me this is what you are
    trying to achieve.
    This is just an example, but you get the idea. Have a good day.

    Alessandro Zifiglio

    "Christophe Peillet" <> ha scritto nel
    messaggio news:...
    >I have a base custom control called 'WebBox' that contains a single
    > EditableDesignerRegion. The contents of this EditableDesignerRegion are
    > stored in an ITemplate via a property name 'Content', and serialized as an
    > InnerProperty.
    >
    > This all works as expected, renders properly, etc., but I can't figure out
    > how, in a control that inherits WebBox (such as AdvertisementWebBox,
    > SearchWebBox, etc.) to add controls to the ITemplate in code on the Server
    > Side. If I add things in the markup, as below, everything works fine (see
    > inner property names 'Content').
    >
    > <CompanyUI:WebBox ID="SearchWebBox" runat="server" IconWidth="0"
    > SkinID="SearchBox"
    > Title="Search" TitleVisible="True" Width="180px">
    > <Content>
    > <div style="text-align: center">
    > <table border="0" cellpadding="0" cellspacing="0"
    > style="width: 100%">
    > <tr>
    > <td align="left" style="width: 130px" valign="top">
    > <CompanyUI:AdvancedTextBox
    > ID="AdvancedTextBox1"
    > runat="server" LabelPosition="Bottom"
    >
    > Width="130px"></CompanyUI:AdvancedTextBox></td>
    > <td align="center" valign="top">
    > <CompanyUI:AdvancedButton ID="SearchButton"
    > runat="server" Text="go" /></td>
    > </tr>
    > <tr>
    > <td align="left" colspan="2" style="width: 130px"
    > valign="top">
    > <CompanyUI:CompanyHyperLink
    > ID="AdvancedSearchLink" runat="server" Description=""
    > LinkLeaderCssClass=""
    > LinkLeaderImageCssClass=""
    > LinkLeaderImageUrl="" NavigateUrl="~/AdvancedSearch.aspx"
    > TextResourceKey="AdvancedSearch">Advanced
    > Search</CompanyUI:CompanyHyperLink></td>
    > </tr>
    > </table>
    > </div>
    > </Content>
    > </CompanyUI:WebBox>
    >
    > How can I do this in code in another specialized server control, though?
    >
    > In the server control that inherits WebBox, I have tried the following,
    > but
    > with no success.
    >
    > protected override void OnPreRender(EventArgs e)
    > {
    > // Call underlying OnPreRender method
    > base.OnPreRender(e);
    >
    > if (!(this.DesignMode))
    > {
    > // Clear WebBox .Content control collection
    > Control template = new Control();
    > base.Content.InstantiateIn(template);
    >
    > // ToDo: How to add controls to an ITemplate in code?
    >
    > template.Controls.Clear();
    >
    > ... // Add controls to collection
    > ... template.Controls.Add(...) ...
    > }
    > }
    >
    > I want WebBox as a generic control with an empty ITemplate, and in
    > specialized controls that inherit from it to add controls like Search
    > boxes,
    > link listings, etc.
    >
    > Any help on this would be appreciated.
    Alessandro Zifiglio, Apr 10, 2006
    #7
  8. oops, my mistake, now that i read your post (a bit slower this time) it
    seems i have misread your post after all. The urls suggested by Steven Chen
    are correct and the last post he made should answer your question.
    My apologies :)
    Regards,
    Alessandro Zifiglio

    "Alessandro Zifiglio" <> ha scritto nel messaggio
    news:%...
    > hi Christophe, Have you tried to add the information via the ToolboxData
    > Metadata attributes since these are applied to server controls (and to
    > their members) to provide information that is used by design tools, the
    > ASP.NET page parser, the ASP.NET run time, and the common language
    > runtime. Something like the following should work well for you :
    >
    > [ToolboxData("<{0}:WebBox runat=\"server\">" +
    > "<Content>" +
    > " <div style=\"text-align: center\">" +
    > "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"
    > style=\"width: 100%\">" +
    > "<tr>" +
    > "<td> <CompanyUI:AdvancedTextBox ID=\"AdvancedTextBox1\"
    > runat=\"server\" LabelPosition=\"Bottom\"
    > Width=\"130px\"></CompanyUI:AdvancedTextBox></td>" +
    > "</tr>" +
    > "</table>" +
    > "</div>" +
    > "</Content>" +
    > "</{0}:WebBox>"),
    > Designer(typeof(SimpleContainerControlDesigner))]
    > public class WebBox : CompositeControl
    > {//definition for your webbox control}
    >
    > When this control gets dropped in the page, the string passed to the
    > MetaData attribute ToolboxData is rendered into the page as as part of
    > your control, just as you want it. Atleast it seems to me this is what you
    > are trying to achieve.
    > This is just an example, but you get the idea. Have a good day.
    >
    > Alessandro Zifiglio
    >
    > "Christophe Peillet" <> ha scritto nel
    > messaggio news:...
    >>I have a base custom control called 'WebBox' that contains a single
    >> EditableDesignerRegion. The contents of this EditableDesignerRegion are
    >> stored in an ITemplate via a property name 'Content', and serialized as
    >> an
    >> InnerProperty.
    >>
    >> This all works as expected, renders properly, etc., but I can't figure
    >> out
    >> how, in a control that inherits WebBox (such as AdvertisementWebBox,
    >> SearchWebBox, etc.) to add controls to the ITemplate in code on the
    >> Server
    >> Side. If I add things in the markup, as below, everything works fine
    >> (see
    >> inner property names 'Content').
    >>
    >> <CompanyUI:WebBox ID="SearchWebBox" runat="server" IconWidth="0"
    >> SkinID="SearchBox"
    >> Title="Search" TitleVisible="True" Width="180px">
    >> <Content>
    >> <div style="text-align: center">
    >> <table border="0" cellpadding="0" cellspacing="0"
    >> style="width: 100%">
    >> <tr>
    >> <td align="left" style="width: 130px"
    >> valign="top">
    >> <CompanyUI:AdvancedTextBox
    >> ID="AdvancedTextBox1"
    >> runat="server" LabelPosition="Bottom"
    >>
    >> Width="130px"></CompanyUI:AdvancedTextBox></td>
    >> <td align="center" valign="top">
    >> <CompanyUI:AdvancedButton ID="SearchButton"
    >> runat="server" Text="go" /></td>
    >> </tr>
    >> <tr>
    >> <td align="left" colspan="2" style="width: 130px"
    >> valign="top">
    >> <CompanyUI:CompanyHyperLink
    >> ID="AdvancedSearchLink" runat="server" Description=""
    >> LinkLeaderCssClass=""
    >> LinkLeaderImageCssClass=""
    >> LinkLeaderImageUrl="" NavigateUrl="~/AdvancedSearch.aspx"
    >> TextResourceKey="AdvancedSearch">Advanced
    >> Search</CompanyUI:CompanyHyperLink></td>
    >> </tr>
    >> </table>
    >> </div>
    >> </Content>
    >> </CompanyUI:WebBox>
    >>
    >> How can I do this in code in another specialized server control, though?
    >>
    >> In the server control that inherits WebBox, I have tried the following,
    >> but
    >> with no success.
    >>
    >> protected override void OnPreRender(EventArgs e)
    >> {
    >> // Call underlying OnPreRender method
    >> base.OnPreRender(e);
    >>
    >> if (!(this.DesignMode))
    >> {
    >> // Clear WebBox .Content control collection
    >> Control template = new Control();
    >> base.Content.InstantiateIn(template);
    >>
    >> // ToDo: How to add controls to an ITemplate in code?
    >>
    >> template.Controls.Clear();
    >>
    >> ... // Add controls to collection
    >> ... template.Controls.Add(...) ...
    >> }
    >> }
    >>
    >> I want WebBox as a generic control with an empty ITemplate, and in
    >> specialized controls that inherit from it to add controls like Search
    >> boxes,
    >> link listings, etc.
    >>
    >> Any help on this would be appreciated.

    >
    >
    Alessandro Zifiglio, Apr 10, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Micke Andersson

    Problem with EditableDesignerRegion and Set/Get methods ..

    Micke Andersson, Jul 31, 2006, in forum: ASP .Net Building Controls
    Replies:
    4
    Views:
    130
    Alessandro Zifiglio
    Aug 3, 2006
  2. Perecli Manole

    ITemplate and inbedded controls

    Perecli Manole, Dec 18, 2006, in forum: ASP .Net Building Controls
    Replies:
    1
    Views:
    103
    Milosz Skalecki
    Dec 22, 2006
  3. Luhar Powell via .NET 247

    Itemplate sample : Access controls on postback

    Luhar Powell via .NET 247, Apr 1, 2005, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    358
    Brock Allen
    Apr 1, 2005
  4. Brook

    Custom Control, ITemplate and nested bound controls

    Brook, Mar 17, 2008, in forum: ASP .Net Web Controls
    Replies:
    4
    Views:
    436
    Brook
    Mar 25, 2008
  5. George

    Persist viewstate in ITemplate child controls

    George, Nov 13, 2009, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    972
    George
    Nov 13, 2009
Loading...

Share This Page