Mar 2, 2011

An ASP.NET Repeater control that supports an empty template

One thing that always bugged me and felt lacking from the otherwise useful Repeater control is support for an empty template. Some of the other templated controls have this, but not Repeater. And yet, so often I'd want to have something nice to show in the case that there wasn't anything to repeat.

I know, I know: why not just show something else if the data is empty? Well, maybe so, but what if I have something in the repeater's header and footer that I still want to show but just show something special between them? Enter my super-duper EnhancedRepeater! (You can rename it whatever you want, I won't mind.)

/// <summary>
/// A <see cref="T:System.Web.UI.WebControls.Repeater"/> that additionally
/// supports an EmptyDataTemplate.
/// </summary>
[DefaultEvent("ItemCommand")]
[DefaultProperty("DataSource")]
[ToolboxData("<{0}:EnhancedRepeater runat=\"server\"></{0}:EnhancedRepeater>")]
public class EnhancedRepeater : System.Web.UI.WebControls.Repeater
{
    private ITemplate emptyTemplate;

    /// <summary>
    /// Gets or sets the <see cref="System.Web.UI.ITemplate"/> that defines
    /// how the control body is rendered when no data is bound.
    /// </summary>
    /// <value>The empty template.</value>
    [Browsable(false),
    Category("Data"),
    Description("The template that defines how the control body is rendered when no data is bound."),
    DefaultValue(null),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
    PersistenceMode(PersistenceMode.InnerProperty),
    TemplateContainer(typeof(RepeaterItem))]
    public ITemplate EmptyTemplate
    {
        get
        {
            return emptyTemplate;
        }
        set
        {
            emptyTemplate = value;
        }
    }

    /// <summary>
    /// Creates child controls and handles empty cases.
    /// </summary>
    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        HandleEmptyData();
    }
    /// <summary>
    /// Raises the DataBinding event.
    /// </summary>
    /// <param name="e">
    /// An <see cref="T:System.EventArgs"></see> that contains the event data.
    /// </param>
    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);

        HandleEmptyData();
    }

    private void HandleEmptyData()
    {
        if (this.Items.Count <= 0 && EmptyTemplate != null)
        {
            this.Controls.Clear();

            if (HeaderTemplate != null)
            {
                HeaderTemplate.InstantiateIn(this);
            }

            EmptyTemplate.InstantiateIn(this);

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

No comments:

Post a Comment