default heading

 

The IRepeatInfoUser Interface...

The IRepeatInfoUser interface is a helpful interface for generating repetitive information in a tabular way...


By: Brian Mains Spacer Date: January 22, 2006Spacer Download Spacer Download the code. Spacer Spacer Printer Friendly Version

The IRepeatInfoUser interface is a helpful interface for generating repetitive information in a tabular way. You've seen this functionality with the checkboxlist control, where you can change the RepeatDirection and RepeatColumns to create a directional or tabular layout. It gives the developer more capabilities when designing web pages to change the layout rendered for the control, and is actually easy to do.

When implementing IRepeatInfoUser, the following properties/methods are added to your control, which are:

  • GetItemStyle - Returns the style for the item currently being rendered.
  • HasFooter - Readonly property stating whether the control has a footer.
  • HasHeader - Readonly property stating whether the control has a header.
  • HasSeparator - Readonly property stating whether the control has a separator.
  • RenderItem - This method renders the specific item.
  • RepeatedItemCount - This property returns the number of items to repeat.

In addition to writing code for these properties/methods, we will need to add three more custom properties in our control, which are the Count, Direction, and Layout properties. These properties affect how the control is rendered, are used at Rendering time, and are not implemented by the interface. The first one is of type integer and the last two are enumerations, as declared below:

private int _count = 0;
public int Count
{
   get { return _count; }
   set { _count = value; }
}

private RepeatDirection _dir = RepeatDirection.Horizontal;
public RepeatDirection Direction
{
   get { return _dir; }
   set { _dir = value; }
}

private RepeatLayout _layout = RepeatLayout.Table;
public RepeatLayout Layout
{
   get { return _layout; }
   set { _layout = value; }
}

Let me explain RenderItem first before explaining the properties. RenderItem fires once for every item in the target collection. The method has a ListItemType enumeration that determines where the control is in the rendering. So, it has an enumeration value for the Header, Footer, Item, AlternatingItem, Separator, etc. So when it runs, RenderItem fires for the Header, then Item, then Separator, then AlternatingItem, and to Footer, leaving out the other enumerated types.

Let's look at the first three implemented properties, which affect how many times RenderItem fires. HasHeader, HasFooter, and HasSeparator determine whether the RenderItem method fires for the Header, Footer, and Separator sections of the control. Based on the boolean value returned, the control will render those items; the problem with the properties is that they are readonly, and thus the ability to render them must be determined from other properties, the existence of a template, etc. I also added the Browsable attribute to hide them from the PropertyGrid. If you notice, when you select the control in the ASPX page, you can't see these properties; that's the function of the Browsable attribute.

[Browsable(false)]
public bool HasFooter
{
   get { return false; }
}

[Browsable(false)]
public bool HasHeader
{
   get { return false; }
}

[Browsable(false)]
public bool HasSeparators
{
   get { return true; }
}

So, these properties turn on/off certain sections of the control. GetItemStyle, on the other hand, returns the appropriate style for the control based on the same enumeration. GetItemStyle has all the necessary information to make that determination based on the enumeration and the index of the control, which your code will return the appropriate style.

public Style GetItemStyle(ListItemType itemType, int repeatIndex)
{
   if (itemType == ListItemType.Item)
     //Use an item style instead if desired
     return this.ControlStyle;
   else if (itemType == ListItemType.AlternatingItem)
     //Use an alternating item style instead if desired
     return this.ControlStyle;
   else
     return this.ControlStyle;
}

Now to the code of RenderItem; RenderItem renders the HTML for the item, using the HTMLTextWriter object. Alternatively, you can create server controls and invoke the RenderControl method of this control to render the HTML to the writer, which is a better approach for more complex controls.

public void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
{
   if (itemType == ListItemType.Separator)
   {
     writer.Write("   ");
   }
   else
   {
     //Normally you do something with the style, like apply it
     //to a server-side control which you render through RenderControl()
     Style style = this.GetItemStyle(itemType, repeatIndex);
     Entry entry = this.Entries[repeatIndex];
     string title = entry.Title;
     string text = entry.Text;

     writer.Write("<table><tr><td>" + title + "</td></tr>");
     writer.Write("<tr><td>" + text + "</td></tr></table>");
   }
}

So how does the control know how many items to render? That is handled by the RepeatedItemsCount readonly property, which returns the count from the collection.

[Browsable(false)]
public int RepeatedItemCount
{
   get { return base.Entries.Count; }
}

Lastly, how is it rendered? Render instantiates a RepeatInfo object with all of the required information, and makes a call to RenderRepeater, which will fire the RenderItem method and pass in all the necessary information for you.

protected override void Render(HtmlTextWriter writer)
{
   base.AddAttributesToRender(writer);

   RepeatInfo info = new RepeatInfo();
   info.RepeatColumns = this.Count;
   info.RepeatDirection = this.Direction;
   info.RepeatLayout = this.Layout;
   info.RenderRepeater(writer, this, this.ControlStyle, this);
}

IRepeatInfoUser is a handy interface and works well with your custom controls in several situations, especially for list controls who want to render in a table structure. It is an excellent interface to consider when designing custom controls. The example control provided, NewsRepeater, inherits the list from NewsControl class, which implements a custom list property named Entries. It renders entries in a table format as defined by the control developer. For this example, only the default.aspx and the NewsRepeater.cs class are used; all others can be ignored.

 
 
 
 
   © Copyright 2002-2012 DotNetJohn.com LLC
Terms of Use Privacy Policy