tags:

views:

2708

answers:

3

I am trying to create nested repeaters dynamically using ITemplate. This repeater is like that I am passing List<Control> and it generates repeater. Issue is that when I databound outer repeater. Only the last nested repeater shows. Following is screen shot.

Markup


    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Restricted_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <table style="border:solid 1px black;">
        <tr>
            <td>
                <asp:PlaceHolder ID="phControls" runat="server" />
            </td>
        </tr>
    </table>
    </div>
    </form>
</body>
</html>


Code Behind



using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

public partial class Restricted_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        CreateNestedRepeater();
    }

    private void CreateNestedRepeater()
    {
        Repeater childRpt = new Repeater();
        List repeatingRuleControls = new List();
        repeatingRuleControls.Add(new TextBox());
        repeatingRuleControls.Add(new TextBox());
        repeatingRuleControls.Add(new TextBox());
        RepeatingRuleTemplate repeatingRuleTemplate = new RepeatingRuleTemplate(ListItemType.Item, repeatingRuleControls);
        childRpt.HeaderTemplate = new RepeatingRuleTemplate(ListItemType.Header, repeatingRuleControls);
        childRpt.ItemTemplate = repeatingRuleTemplate;
        childRpt.FooterTemplate = new RepeatingRuleTemplate(ListItemType.Footer, null);
        childRpt.DataSource = new DataRow[4];

        Repeater parentRpt = new Repeater();
        repeatingRuleControls = new List();
        repeatingRuleControls.Add(new TextBox());
        repeatingRuleControls.Add(new TextBox());
        repeatingRuleControls.Add(new TextBox());
        repeatingRuleControls.Add(childRpt);
        RepeatingRuleTemplate parentrepeatingRuleTemplate = new RepeatingRuleTemplate(ListItemType.Item, repeatingRuleControls);
        parentRpt.HeaderTemplate = new RepeatingRuleTemplate(ListItemType.Header, repeatingRuleControls);
        parentRpt.ItemTemplate = parentrepeatingRuleTemplate;
        parentRpt.FooterTemplate = new RepeatingRuleTemplate(ListItemType.Footer, null);
        parentRpt.DataSource = new DataRow[4];
        parentRpt.DataBind();
        phControls.Controls.Add(parentRpt);
    }

    public class RepeatingRuleTemplate : ITemplate
    {
        ListItemType templateType;
        List innerControls;

        public RepeatingRuleTemplate(ListItemType type, List controls)
        {
            templateType = type;
            innerControls = controls;
        }



        public void InstantiateIn(Control container)
        {
            PlaceHolder ph = new PlaceHolder();

            switch (templateType)
            {
                case ListItemType.Header:
                    ph.Controls.Add(new LiteralControl(""));
                    ph.Controls.Add(new LiteralControl(""));
                    foreach (Control control in innerControls)
                    {
                        Label label = new Label();
                        label.Text = control.ID;
                        ph.Controls.Add(new LiteralControl(""));
                        ph.Controls.Add(label);
                        ph.Controls.Add(new LiteralControl(""));
                    }
                    ph.Controls.Add(new LiteralControl(""));
                    break;
                case ListItemType.Item:
                    ph.Controls.Add(new LiteralControl(""));

                    foreach (Control control in innerControls)
                    {
                        if (control.GetType() != typeof(Repeater))
                        {
                            ph.Controls.Add(new LiteralControl(""));
                            TextBox textBox = new TextBox();
                            textBox.ID = control.ID;
                            ph.Controls.Add(textBox);
                            ph.Controls.Add(new LiteralControl(""));
                        }
                        else
                        {
                            ph.Controls.Add(new LiteralControl(""));
                            ph.Controls.Add(control as Repeater);
                            //(control as Repeater).DataSource = new DataRow[4];
                            //   (control as Repeater).DataBind();
                            ph.Controls.Add(new LiteralControl(""));
                        }
                    }
                    ph.Controls.Add(new LiteralControl(""));
                    //ph.DataBinding += new EventHandler(Item_DataBinding);
                    break;
                case ListItemType.Footer:
                    ph.Controls.Add(new LiteralControl(""));
                    break;
            }
            container.Controls.Add(ph);
        }



        public List Controls
        {
            get
            {
                return innerControls;
            }
        }

    }
}


A: 

You need to write handler for parentRpt.ItemDataBound event and set DataSource property of childRpt and then call child.Rpt.DataBind() from there.

radimd
As per my knowledge call to databind is hierarchical. I mean call to parent will cause all the child controls to databind as will. This is what is happeneing. Otherwise even the last row wouls not show up..
Mohit
A: 

Why not just to make build custom control and fill it with your code?

override CreateChildControls(){  

    foreach(var r in rows)
    {
    ...
    }
}

Templates, repreaters and so on are just to make design expirience better, in your situation when you build all manually I cannot see a reason why overcomplicate with all that placeholder, templates and so on...

Just build CompositeControl and fill it with your code. You will reduce your code twice and what is the best you will have readable code. Witout nasty events to wire child repreaters DataSource properties.

Sorry for hard offtop...

Mike Chaliy
It can be a solution. But, this question is small picutre of whole problem. Wht I m trying to do is generate nested rpts frm xml.Tht xml is actually a standard defined by our comp to validate controls inside repeaters. I m trying to generate UI to test those rules. So, I hve to use rpts.
Mohit
this is my first time on stack overflow.So I thought I can't comment again. Thats why I used chat language. Sorry for that.
Mohit
A: 
Mohit