views:

26

answers:

2

If I have a custom user control (say, MyCustomControl.ascx) which contains a number of other controls including a repeater, is there any way to expose that repeater's templates as templates for MyCustomControl?

For example, I would want to be able to do this:

<uc:MyCustomControl ID="MyCustomControl1" runat="server">
    <ChildRepeaterHeaderTemplate>
        <!-- code goes here -->
    </ChildRepeaterHeaderTemplate>
    <ChildRepeaterItemTemplate>
        <!-- code that accesses values on the repeater's DataItem goes here -->
    </ChildRepeaterItemTemplate>
    <ChildRepeaterFooterTemplate>
        <!-- code goes here -->
    </ChildRepeaterFooterTemplate>
</uc:MyCustomControl>

There could potentially be more than one repeater or other templated controls within the parent control, in which case I would like to be able to expose all of those templates for all of the controls in the same way.

My first thought was to simply expose the repeater's templates as ITemplate properties on MyCustomControl, but that didn't work since there's no (obvious) way to access the repeater's DataItem from the templates doing it that way.

+1  A: 

Hey,

Sounds like more of a custom control (not custom user control) to me... but that might add a lot of complexity... you could try to expose ChildRepeaterItemTemplate as a property, then programmably set the template on each child item when data binding... that might work.

HTH.

Brian
That was the approach I tried, but wasn't able to access the repeater's data from the templates that way.
Rudism
+1  A: 

Like Brian says, you need a custom control, but if you had that, you could expose the ItemTemplates.

namespace MyControls
{
    public class MyControl : System.Web.UI.WebControls.WebControl
    {
        System.Web.UI.WebControls.Repeater FirstRepeater = new System.Web.UI.WebControls.Repeater();
        System.Web.UI.WebControls.Repeater SecondRepeater = new System.Web.UI.WebControls.Repeater();

        [System.Web.UI.PersistenceMode(System.Web.UI.PersistenceMode.InnerProperty)]
        public System.Web.UI.ITemplate FirstTemplate
        {
            get
            {
                return FirstRepeater.ItemTemplate;
            }
            set
            {
                FirstRepeater.ItemTemplate = value;
            }
        }

        [System.Web.UI.PersistenceMode(System.Web.UI.PersistenceMode.InnerProperty)]
        public System.Web.UI.ITemplate SecondTemplate
        {
            get
            {
                return SecondRepeater.ItemTemplate;
            }
            set
            {
                SecondRepeater.ItemTemplate = value;
            }
        }

        protected override void CreateChildControls()
        {
            base.Controls.Add(FirstRepeater);
            object[] FirstDataSource = {
                new { x = "1" },
                new { x = "2" },
                new { x = "3" },
                new { x = "4" }
            };
            FirstRepeater.DataSource = FirstDataSource;
            FirstRepeater.DataBind();

            base.Controls.Add(SecondRepeater);
            object[] SecondDataSource = {
                new { y = "a" },
                new { y = "b" },
                new { y = "c" },
                new { y = "d" }
            };
            SecondRepeater.DataSource = SecondDataSource;
            SecondRepeater.DataBind();

            base.CreateChildControls();
        }
    }
}

You need to instantiate your child repeaters before the control that includes this one tries to assign them. This sample creates two child repeaters inside the control and binds them to some dummy data.

And with a page that uses this control:

<%@ Page %>

<%@ Register Namespace="MyControls" TagPrefix="mc" %>
<!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 runat="server">
    <div>
        <mc:MyControl runat="server">
            <FirstTemplate>
                <div style="color: blue">
                    <%# Eval("x")%>
                </div>
            </FirstTemplate>
            <SecondTemplate>
                <div style="color: red">
                    <%# Eval("y")%>
                </div>
            </SecondTemplate>
        </mc:MyControl>
    </div>
    </form>
</body>
</html>

You get the following output:

<!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><title> 

</title></head> 
<body> 
    <form method="post" action="" id="ctl01"> 
<div class="aspNetHidden"> 
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEwMjEyMzEwMzcPZBYCAgMPZBYCAgEPZBYEZg8WAh4LXyFJdGVtQ291bnQCBBYIZg9kFgJmDxUBATFkAgEPZBYCZg8VAQEyZAICD2QWAmYPFQEBM2QCAw9kFgJmDxUBATRkAgEPFgIfAAIEFghmD2QWAmYPFQEBMmQCAQ9kFgJmDxUBAWJkAgIPZBYCZg8VAQFjZAIDD2QWAmYPFQEBZGRk7v0uzzMp0h89eUJash2eToIH2EboQLSZWnkVYXRsGpM=" /> 
</div> 

    <div> 
        <span> 
                <div style="color: blue"> 
                    1
                </div> 

                <div style="color: blue"> 
                    2
                </div> 

                <div style="color: blue"> 
                    3
                </div> 

                <div style="color: blue"> 
                    4
                </div> 

                <div style="color: red"> 
                    a
                </div> 

                <div style="color: red"> 
                    b
                </div> 

                <div style="color: red"> 
                    c
                </div> 

                <div style="color: red"> 
                    d
                </div> 
            </span> 
    </div> 
    </form> 
</body> 
</html>
langsamu