This is a migrated thread and some comments may be shown as answers.

Binding with templates

10 Answers 179 Views
PanelBar
This is a migrated thread and some comments may be shown as answers.
Cris
Top achievements
Rank 1
Cris asked on 20 May 2009, 03:14 PM
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

10 Answers, 1 is accepted

Sort by
0
Paul
Telerik team
answered on 21 May 2009, 07:19 AM
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.
0
Cris
Top achievements
Rank 1
answered on 21 May 2009, 07:52 AM
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
0
Stuart Hemming
Top achievements
Rank 2
answered on 21 May 2009, 08:40 AM
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
0
Cris
Top achievements
Rank 1
answered on 21 May 2009, 10:22 AM
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
0
Stuart Hemming
Top achievements
Rank 2
answered on 21 May 2009, 10:39 AM
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

0
Cris
Top achievements
Rank 1
answered on 21 May 2009, 10:57 AM

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  
    } 

 

 

 

 

 

0
Stuart Hemming
Top achievements
Rank 2
answered on 21 May 2009, 11:02 AM
Could you post your code again without all of the HTML tags?

--
Stuart
0
Cris
Top achievements
Rank 1
answered on 21 May 2009, 11:12 AM
Hey, sorry about that, already cleaned it up.
0
Stuart Hemming
Top achievements
Rank 2
answered on 21 May 2009, 11:28 AM
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


0
Beth Krawczuk
Top achievements
Rank 1
answered on 08 Sep 2009, 10:14 PM
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
Tags
PanelBar
Asked by
Cris
Top achievements
Rank 1
Answers by
Paul
Telerik team
Cris
Top achievements
Rank 1
Stuart Hemming
Top achievements
Rank 2
Beth Krawczuk
Top achievements
Rank 1
Share this question
or