Binding with templates

11 posts, 0 answers
  1. Cris
    Cris avatar
    27 posts
    Member since:
    Aug 2006

    Posted 20 May 2009 Link to this post

    Hi,

    I managed to do this: have a panel bar with a IEnumerable data source (List<Address>). I have a template defined for the panelitem and it populates just fine with the contents of each address objects in the template.

    However, the panel bar items do not collapse/expand, they're fixed and all visible. I would like each item to be collapsable, so basically I would like each template to be inside another radpanelitem I figure. Any example/suggestion would be appreciated.

    Thanks
  2. Paul
    Admin
    Paul avatar
    4281 posts

    Posted 21 May 2009 Link to this post

    Hello Cris,

    I guess there's some misunderstanding here. Let me explain.

    You cannot collapse a header panel item with a template. Here's a sample:

    Item1
    --template
    Item2
    --template

    In this case, you cannot collapse Item1 and Item2.

    Here's how the panelbar structure should look as to achieve your goal:

    Item1
    -- (RadpanelItem without text)
        --template
    Item2
    -- (RadpanelItem without text)
        --template

    Best wishes,
    Paul
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Cris
    Cris avatar
    27 posts
    Member since:
    Aug 2006

    Posted 21 May 2009 Link to this post

    Hey - thanks for the reply. I got that, however my problem is that I don't know how to generate that structure when databinding. When I set an IEnumerable as Datasource and call Databind, the binding generates header items. How would I make it generate RadPanelItems as well? I tried adding a RadPanelItem in the template but it won't work...

    Thanks,
    Cris
  5. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 21 May 2009 Link to this post

    Cris,

    I've just been though this.

    You can do it by wring up the ItemCreated event ...
        protected void RadPanelBar1_ItemCreated(object sender, RadPanelBarEventArgs e) 
        { 
            if (e.Item.Owner is RadPanelBar) 
            { 
                RadPanelItem i = new RadPanelItem(); 
                e.Item.Items.Add(i); 
            } 
        } 
    The reason for the outer test is that this event is called when you create a new RadPanelItem programmatically so it ends up in an loop that only ends when you run out of memory!

    As an alternative, you could do it in the ItemDataBound event and you wouldn't need the test.

    Hope this helps.

    --
    Stuart
  6. Cris
    Cris avatar
    27 posts
    Member since:
    Aug 2006

    Posted 21 May 2009 Link to this post

    Hey, 

    Thanks Stuart, that almost does it! One more problem though. Now all my items have the same template. I need only the items that expand to have the template applied because as of now I basically see the template repeaded twice (one sliding in and one which doesn't). I tried e.Item.ItemTemplate, but not sure how to clear the template in the root items.

    Thanks again,
    Cris
  7. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 21 May 2009 Link to this post

    I'm sorry mate, I can't quite follow what it is you're trying to achieve.

    If you are saying that you only want to apply your templated control to the items that you expand, then let me point you at this forum article that explains how to do that.

    You should note that the article assumes only one open PanelItem at a time.

    If, like me, you need your PanelBar to allow multipe open items you're going to need to have somethink like the following on your calling page...
        protected override void OnPreRender(EventArgs e) 
        { 
            base.OnPreRender(e); 
            for (int i = 0; i < RadPanelBar1.Items.Count; i++) 
            { 
                if (RadPanelBar1.Items[i].Expanded) 
                { 
                    LoadTemplatedContent(RadPanelBar1.Items[i]); 
                } 
            } 
        } 
    Where the LoadTemplatedContent method calls Page.LoadControl to get your template and adds it to the passed in item's Controls collection.

    You should also note that you need to wire up the ItemClicked event on the PanelBar, even if you leave it empty. If you don't, your template won't get loaded 'cos PanelBar handles the expand/collapse events client-side by default and so your OnPreRender code never gets called.

    If this doesn't help, post again with a bit more detail of what it is you're trying to do.

    --
    Stuart

  8. Cris
    Cris avatar
    27 posts
    Member since:
    Aug 2006

    Posted 21 May 2009 Link to this post

    Thanks for trying to help, sorry I didn't make myself clear. I'll try to detail what I need below:

    I try to achieve this structure:

    Item1
    -- (RadpanelItem without text)
        --template
    Item2
    -- (RadpanelItem without text)
        --template

    I used the ItemCreated method you posted here and that made me obtain this structure:

    Item1
    -- template
        --template
    Item2
    -- template
        --template

    which is logical.
    But I basically need to get to the first variant, so the template is only applied to the leafs of the hierarchy. I tried this, but seems to have no effect:

     

     

     

     

            protected void rpbHQInfo_ItemCreated(object sender, RadPanelBarEventArgs e)  
            {  
                EmptyItemTemplate template = new EmptyItemTemplate();  
                if (e.Item.Owner is RadPanelBar)  
                {  
                    RadPanelItem i = new RadPanelItem();  
                    e.Item.Items.Add(i);  
                    template.InstantiateIn(e.Item);  
                }   
            } 


    with the EmptyTemplateItem class being


     

     

        class EmptyItemTemplate :ITemplate{
            #region ITemplate Members  
     
            public void InstantiateIn(Control container)  
            {  
                return;  
            }
            #endregion  
        } 

     

     

     

     

     

  9. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 21 May 2009 Link to this post

    Could you post your code again without all of the HTML tags?

    --
    Stuart
  10. Cris
    Cris avatar
    27 posts
    Member since:
    Aug 2006

    Posted 21 May 2009 Link to this post

    Hey, sorry about that, already cleaned it up.
  11. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 21 May 2009 Link to this post

    Only reason I can think of for getting the template twice is that you've got it defined in the page/panelbar as well.

    Here is a really trivial example doing all of the steps that I do in my app...
    WebForm3.aspx
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="WebApplication1.WebForm3" %> 
     
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %> 
    <%@ Register Src="WebUserControl1.ascx" TagName="wuc1"TagPrefix="uc4" %> 
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
     
    <html xmlns="http://www.w3.org/1999/xhtml" > 
    <head runat="server"
        <title></title
    </head> 
    <body> 
        <form id="form1" runat="server"
            <telerik:RadScriptManager ID="RadScriptManager1" runat="server"
            </telerik:RadScriptManager> 
             
        <div> 
            <telerik:RadPanelBar ID="RadPanelBar1" runat="server" DataSourceID="sitedata"  
                DataTextField="Text" onitemclick="RadPanelBar1_ItemClick"  
                onitemdatabound="RadPanelBar1_ItemDataBound"
             
            </telerik:RadPanelBar> 
            <asp:ObjectDataSource runat="server" ID="sitedata" TypeName="WebApplication1.SiteDataItem" SelectMethod="GetSiteData"></asp:ObjectDataSource> 
        </div> 
        </form> 
    </body> 
    </html> 

    WebForm3.aspx.cs
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 
     
    using Telerik.Web.UI; 
    namespace WebApplication1 
        public partial class WebForm3 : System.Web.UI.Page 
        { 
            protected override void OnPreRender(EventArgs e) 
            { 
                foreach (RadPanelItem i in RadPanelBar1.Items) 
                { 
                    if (i.Expanded) LoadControls(i); 
                } 
                base.OnPreRender(e); 
            } 
     
            protected void RadPanelBar1_ItemDataBound(object sender, Telerik.Web.UI.RadPanelBarEventArgs e) 
            { 
                RadPanelItem i = new RadPanelItem(); 
                e.Item.Items.Add(i); 
            } 
            void LoadControls(RadPanelItem item) 
            { 
                Control userControl1 = Page.LoadControl("~/WebUserControl1.ascx"); 
                userControl1.ID = "userControl1"
                item.Items[0].Controls.Add(userControl1); 
     
            } 
     
            protected void RadPanelBar1_ItemClick(object sender, RadPanelBarEventArgs e) 
            { 
     
            } 
        } 
     


    WebUserControl1.ascx
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.WebUserControl1" %> 
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %> 
    <telerik:RadTreeView ID="RadTreeView1" runat="server"
      <Nodes> 
        <telerik:RadTreeNode Text="1"></telerik:RadTreeNode> 
        <telerik:RadTreeNode Text="2"
          <Nodes> 
            <telerik:RadTreeNode Text="2_1"></telerik:RadTreeNode> 
            <telerik:RadTreeNode Text="2_2"
              <Nodes> 
                <telerik:RadTreeNode Text="2_2_1"></telerik:RadTreeNode> 
                <telerik:RadTreeNode Text="2_2_2"
                 
                </telerik:RadTreeNode> 
                <telerik:RadTreeNode Text="2_2_3"></telerik:RadTreeNode> 
              </Nodes> 
            </telerik:RadTreeNode> 
            <telerik:RadTreeNode Text="2_3"></telerik:RadTreeNode> 
          </Nodes> 
        </telerik:RadTreeNode> 
        <telerik:RadTreeNode Text="3"></telerik:RadTreeNode> 
      </Nodes> 
    </telerik:RadTreeView> 
     

    And finally, the datasource, fromdatasource.cs
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
     
    namespace WebApplication1 
        #region DataSource 
        public class SiteDataItem 
        { 
            private string _text; 
            private string _url; 
            private int _id; 
            private int _parentId; 
            public string Text 
            { 
                get { return _text; } 
                set { _text = value; } 
            } 
            public string Url 
            { 
                get { return _url; } 
                set { _url = value; } 
            } 
            public int ID 
            { 
                get { return _id; } 
                set { _id = value; } 
            } 
            public int ParentID 
            { 
                get { return _parentId; } 
                set { _parentId = value; } 
            } 
            public SiteDataItem(int id, int parentId, string text, string url) 
            { 
                _id = id; 
                _parentId = parentId; 
                _text = text; 
                _url = url; 
            } 
            public static List<SiteDataItem> GetSiteData() { 
                List<SiteDataItem> siteData = new List<SiteDataItem>()  
                { 
                    new SiteDataItem(1, 0, "All Sites""(none)"), 
                    new SiteDataItem(2, 1, "Search Engines""(none)"), 
                    new SiteDataItem(3, 1, "News Sites""(none)"), 
                    new SiteDataItem(4, 2, "Yahoo""http://www.yahoo.com"), 
                    new SiteDataItem(5, 2, "MSN""http://www.msn.com"), 
                    new SiteDataItem(6, 2, "Google""http://www.google.com"), 
                    new SiteDataItem(7, 3, "CNN""http://www.cnn.com"), 
                    new SiteDataItem(8, 3, "BBC""http://www.bbc.co.uk"), 
                    new SiteDataItem(9, 3, "FOX""http://www.foxnews.com"
                }; 
                return siteData; 
     
            } 
     
        } 
        #endregion 
     

    As you can see, there's no mention of the control as a template (in the ITemplate sence). I load the control only when I need it.

    Does this help?

    --
    Stuart


  12. Beth Krawczuk
    Beth Krawczuk avatar
    26 posts
    Member since:
    Feb 2008

    Posted 08 Sep 2009 Link to this post

    So this solution works for me but now I'm having trouble accessing elements within my usercontrol after a button click.

    When the user hits the save button I'm trying to collect the entered data within each panelbar (usercontrol) and put it into an array list to save.

    I can't seem to find any of my elements within the usercontrol.

    Thanks in advance for any help!
    Beth
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017