views:

179

answers:

5

I want to create a Repeater that displays the header/footer based on properties, only if the DataSource is empty.

public class Repeater : System.Web.UI.WebControls.Repeater
{
    public bool ShowHeaderOnEmpty { get; set; }
    public bool ShowFooterOnEmpty { get; set; }

    [DefaultValue((string)null),
    PersistenceMode(PersistenceMode.InnerProperty),
    TemplateContainer(typeof(System.Web.UI.WebControls.RepeaterItem)),
    Browsable(false)]
    public ITemplate EmptyTemplate { get; set; }
}

I also want to create a EmptyTemplate, if the DataSource is empty display this template...

I have no idea on how to implement this. What should I override to achieve this behavior?

A: 

I would create a Web User Control (.ascx) that contains your header section, a [child] repeater control, and a footer section. You can put all your logic in that custom control.

Coding Gorilla
A: 

If you want to do this with just a repeater you can do this:

    <asp:Repeater runat="server" OnItemDataBound="ShowHideHeaderFooter">
    <HeaderTemplate>
        <asp:PlaceHolder runat="server" ID="PlaceHolderHeader">
            HEADER STUFF
        </asp:PlaceHolder>
    </HeaderTemplate>
    <ItemTemplate>
        ITEM STUFF
    </ItemTemplate>
    <FooterTemplate>
        <asp:PlaceHolder runat="server" ID="PlaceHolderFooter">
            FOOTER STUFF
        </asp:PlaceHolder>
    </FooterTemplate>
</asp:Repeater>

and then in your code behind

    protected void ShowHideHeaderFooter(object sender, RepeaterItemEventArgs e)
    {
        if(e.Item.ItemType == ListItemType.Header && theDataSource.Count == 0 && !ShowHeaderOnEmpty)
        {
            e.Item.FindControl("PlaceHolderHeader").Visible = false;
        }
        ...
    }
AndreasKnudsen
The problem with this is that the repeater will not fire its rendering event if no records were bound through the data binding process. This is similar to the problem you run into when you want to have a custom footer to add records in a GridView and you have no data.
Dillie-O
i stand corrected. Thank you
AndreasKnudsen
+2  A: 

Use ListView instead of Repeater. It already contains EmptyDataTemplate and EmptyItemTemplate elements so you don't need to do anything :)

Patrol02
A: 

override the render event to output the HTML you want based on the all properties you have mentioned.

Vinay B R
+2  A: 
[ToolboxData("<{0}:SmartRepeater runat=\"server\"></{0}:SmartRepeater>")]
public partial class SmartRepeater : Repeater
{
    public bool ShowHeaderOnEmpty { get; set; }
    public bool ShowFooterOnEmpty { get; set; }

    private ITemplate emptyTemplate = null;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    public ITemplate EmptyTemplate
    {
        get { return this.emptyTemplate; }
        set { this.emptyTemplate = value; }
    }

    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);
        if (this.Items.Count == 0)
        {
            this.Controls.Clear();

            if (this.HeaderTemplate != null && ShowHeaderOnEmpty)
                this.HeaderTemplate.InstantiateIn(this);

            if (this.EmptyTemplate!=null)
                this.EmptyTemplate.InstantiateIn(this);

            if (this.FooterTemplate != null && ShowFooterOnEmpty)
                this.FooterTemplate.InstantiateIn(this);
        }
    }
}

Usage:

<UC:SmartRepeater ID="rep" runat="server" ShowHeaderOnEmpty="true" ShowFooterOnEmpty="true">
    <HeaderTemplate>HEADER</HeaderTemplate>
    <ItemTemplate>Item</ItemTemplate>
    <SeparatorTemplate>, </SeparatorTemplate>
    <EmptyTemplate><b>Nothing</b></EmptyTemplate>
    <FooterTemplate>FOOTER</FooterTemplate>
</UC:SmartRepeater>
Pavlo Neyman
Thanks! That is exactly what I was looking for!
BrunoLM