Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

ASP.NET Custom Repeater Control with EmptyTemplate, ShowHeaderWhenEmpty, ShowFooterWhenEmpty, ShowCount Properties

5.00/5 (5 votes)
4 Apr 2011CPOL3 min read 26.5K  
ASP.NET Custom Repeater Control with EmptyTemplate, ShowHeaderWhenEmpty, ShowFooterWhenEmpty, ShowCount Properties

image

If you have worked with ASP.NET GridView Control, you must be aware of GridView.EmptyDataTemplate Property which gets or sets the user-defined content for the empty data row when a GridView control data source has no records. Similarly ShowHeaderWhenEmpty property allows you to show or hide the Header row when there are no records. These are the really good and very frequent required properties. Now, if you are working with the Repeater Control, it doesn’t have any direct features which enable you to set user defined content when data source is empty. In this blog post, I will discuss how we can create a custom ASP.NET Repeater control with support of EmptyTemplate along with few more important features.

The basis of the complete implementation stands on developing a custom ASP.NET Control. Here, I will be developing a custom ASP.NET Repeater control which inherits from Repeater as you can see in the below code snippet.

image

Now, once you inherit your control from default Repeater control, you have access to all methods and properties of Repeater control. The most important thing here is that you need to know about ITemplate Interface. ITemplate defines the behavior for populating a templated ASP.NET server control with child controls. These ITemplate has a method InstantiateIn which actually instantiates the template within the control object. As we required a Template here, I created a property named “EmptyTemplate” of type “ITemplate”.

C#
[PersistenceMode(PersistenceMode.InnerProperty)]
     public ITemplate EmptyTemplate
     {
         get;
         set;
     }

In the above code snippets, you have noticed that I have added one attribute as:

C#
PersistenceMode(PersistenceMode.InnerProperty)]

These actually define the type of the property with PersistenceMode Enumeration. InnerProperty tells the control that these properties should be used a inner nested tag not as top level attributes. I discussed about few other values in a later part of this article.

Once we are done with the Property definition, we just need to override the CreateChildControls() and OnDataBinding() Events.

C#
/// <summary>
/// Creates the child controls.
/// </summary>
protected override void CreateChildControls()
{
    base.CreateChildControls();
    EnabledEmptyTemplate();
}

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

}

/// <summary>
/// Enableds the empty template.
/// </summary>
private void EnabledEmptyTemplate()
{
    if (this.Items.Count <= 0 && EmptyTemplate != null)
    {
        this.Controls.Clear();

        EmptyTemplate.InstantiateIn(this);

    }
}

While overriding those methods, I have internally called a method EnabledEmptyTemplate() which actually checks for the Item Counts, if its &lt;=0, it will instantiate the EmptyTemplate.

That’s all. If you build the control, you will get a Control Icon with in ToolBox, which you can directly drag and drop.

image

Now let’s consider you have below Student Data Source which you want to bind with this gridview.

Sample Student Data Source and binding with repeater:

C#
public partial class _Default : System.Web.UI.Page
  {
      protected void Page_Load(object sender, EventArgs e)
      {
          List<MyClass> names = new List<MyClass>()
          {
          new MyClass { Name ="Student 1", Address="Address 1"},
          new MyClass { Name ="Student 2", Address="Address 2"},
          new MyClass { Name ="Student 3", Address="Address 3"},
          new MyClass { Name ="Student 4", Address="Address 4"}
          };
                ExRepeater1.DataSource = names;
          ExRepeater1.DataBind();
      }
  }

  class MyClass
  {
      public string Name { get; set; }
      public string Address { get; set; }
  }

Design View for Custom Repeater:

HTML
<cc1:ExRepeater ID="ExRepeater1" runat="server"  >
        <HeaderTemplate>
            <table>
                <tr>
                    <td>
                        Name
                    </td>
                    <td>
                        Address
                    </td>
                </tr>
             </HeaderTemplate>
        <ItemTemplate>
            <tr>
                <td>
                    <%#Eval("Name")%>
                </td>

                <td>
                    <%#Eval("Address")%>
                </td>
            </tr>
        </ItemTemplate>
        <EmptyTemplate>
           <tr><td> No Records Exist !!!!</td></tr>
        </EmptyTemplate>
        <FooterTemplate>
        </table>
        </FooterTemplate>
    </cc1:ExRepeater>

Output:

image

Now, if there are no records in the data source, output will look like below:

image

Well, this is exactly what we were looking for. So now, you have one Template called “EmptyTemplate” where you can put whatever content you want rendered if the data source is empty.

ShowHeaderWhenEmpty

You have noticed the message “No Records Exists” is being displayed along with the header. Now if you want the same features like GridView, you need control on the showing or hiding header when records is empty.

Let’s add a bool type property with name ShowHeaderWhenEmpty:

image

This property will accepts a Boolean value based on that Header will be shown. One more point over here is, PersistenceMode.Attribute, which means I am going to use the properties as a top level attributes tag. So ShowHeaderWhenEmpty will be accessible as shown below:

image

Below snippets describe how to implement the ShowHeaderWhenEmpty properties.

C#
/// <summary>
/// Enableds the empty template.
/// </summary>
private void EnabledEmptyTemplate()
{
    if (this.Items.Count <= 0 && EmptyTemplate != null)
    {
        this.Controls.Clear();

        // Instantiate Header Template When Item count 0
        if (ShowHeaderWhenEmpty == true)
        {
            HeaderTemplate.InstantiateIn(this);
        }

        EmptyTemplate.InstantiateIn(this);
    }
}

ShowFooterWhenEmpty

Like Header, you can implement the same to show or hide footer when there are no records in repeater.

image

C#
/// <summary>
/// Enableds the empty template.
/// </summary>
private void EnabledEmptyTemplate()
{
    if (this.Items.Count <= 0 && EmptyTemplate != null)
    {
        this.Controls.Clear();
        EmptyTemplate.InstantiateIn(this);
    // Instantiate Footer Template When Item count 0
        if (ShowFooterWhenEmpty == true)
        {
            FooterTemplate.InstantiateIn(this);
        }

    }
}

ShowCount

By this property, I just wanted to show the customization or enhancement idea. Let’s say you want to display the number of total records at the end of the repeater, so by using these properties, you can enable or disable it.

image

If you make it true, you will get the number of records count at the end of repeater records.

image

Below is the implementation for the same:

C#
/// <summary>
  /// Enableds the empty template.
  /// </summary>
  private void EnabledEmptyTemplate()
  {
      if (this.Items.Count <= 0 && EmptyTemplate != null)
      {
          this.Controls.Clear();

          // Instantiate Header Template When Item count 0
          if (ShowHeaderWhenEmpty == true)
          {
              HeaderTemplate.InstantiateIn(this);
          }

          EmptyTemplate.InstantiateIn(this);
      }
  }

ShowFooterWhenEmpty

Like Header, you can implement the same to show or hide footer when there are no records in repeater.

image

C#
        /// <summary>
        /// Raises the DataBinding event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> 
        /// object that contains the event data.</param>
        protected override void OnDataBinding(EventArgs e)
        {
            base.OnDataBinding(e);
            EnabledEmptyTemplate();
            if (ShowCount == true)
            {
                this.Controls.Add(new LiteralControl
                ("<br/>Total Number of Records : " + this.Items.Count ));
            }
        }

Put everything together:

C#
// Custom Repeater With EmptyItemTemplate and ShowHeaderWhenEmpty Properties
namespace RepeaterTest
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    using System.Web.UI;

    /// <summary>
    /// Advance ASP.NET Repeater with EmptyTemplate, ShowHeaderWhenEmpty, ShowFooterWhenEmpty
    /// </summary>
    [ToolboxData("<{0}:ExRepeater runat="server">")]
    public class ExRepeater : Repeater
    {
        #region Repeater Properties

        /// <summary>
        /// Gets or sets a value indicating whether [show header when empty].
        /// </summary>
        /// <value>
        /// 	<c>true</c> if [show header when empty]; 
        /// otherwise, <c>false</c>.
        /// </value>
        [PersistenceMode(PersistenceMode.Attribute)]
        public bool ShowHeaderWhenEmpty
        {
            get;
            set;
        }

        [PersistenceMode(PersistenceMode.Attribute)]
        public bool ShowFooterWhenEmpty
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the empty template.
        /// </summary>
        /// <value>The empty template.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate EmptyTemplate
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the empty template.
        /// </summary>
        /// <value>The empty template.</value>
        [PersistenceMode(PersistenceMode.Attribute)]
        public bool ShowCount
        {
            get;
            set;
        }

        #endregion

        #region Repeater Methods

        /// <summary>
        /// Creates the child controls.
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            EnabledEmptyTemplate();
        }

        /// <summary>
        /// Raises the DataBinding event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> 
        /// object that contains the event data.
        /// </param>
        protected override void OnDataBinding(EventArgs e)
        {
            base.OnDataBinding(e);
            EnabledEmptyTemplate();
            if (ShowCount == true)
            {
                this.Controls.Add(new LiteralControl("<br/>Total Number of Records : " + 
                    this.Items.Count ));
            }
        }

        /// <summary>
        /// Enableds the empty template.
        /// </summary>
        private void EnabledEmptyTemplate()
        {
            if (this.Items.Count <= 0 && EmptyTemplate != null)
            {
                this.Controls.Clear();

                // Instantiate Header Template When Item count 0
                if (ShowHeaderWhenEmpty == true)
                {
                    HeaderTemplate.InstantiateIn(this);
                }

                EmptyTemplate.InstantiateIn(this);
            }
        }

        #endregion
    }
}

Summary

In this post, I have explained how you can customize your repeater control by adding must needed features like EmptyTemplate, ShowHeaderWhenEmpty, ShowFooterWhenEmpty, ShowCount.

Hope this will help!

Cheers !
AJ

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)