GeekZilla
Restricting the number of rows in a dataview when binding to a repeater
The problem
I needed to restrict the number of items bound to an asp:repeater. Basically I never wanted more than 10 items to be displayed.
Options
The right thing to do would be to restrict the number of items at the database level using Set RowCount or top 10.
In this instance, it wasn't an option and the lack of a RowCount feature on the DataView object left me needing to find another solution.
The Solution
After some searching, I came across a bit of code which proved helpful. The following code makes allows me to pass a DataView into an enumerable object which returns only the number of rows I'm interested in.
Example Use
myRepeater.DataSource = new FilterRows(myDataView, 10);
The Enumerable Object
using System; using System.Data; using System.Web.Security; using System.Collections; /// <summary> /// Summary description for FilterRows /// </summary> public class FilterRows : IEnumerable { DataView dataView; private int rowsToShow; public FilterRows(DataView dataView, int rowsToShow) { this.rowsToShow = rowsToShow; this.dataView = dataView; } public IEnumerator GetEnumerator() { return new PageOfData(this.dataView.GetEnumerator(), this.rowsToShow); } internal class PageOfData : IEnumerator { private IEnumerator e; private int cnt = 0; private int rowsToShow; internal PageOfData(IEnumerator e, int rowsToShow) { this.rowsToShow = rowsToShow; this.e = e; } public object Current { get { return e.Current; } } public bool MoveNext() { // If we've hit out limit return false if (cnt >= rowsToShow) return false; // Track the current row cnt++; return e.MoveNext(); } public void Reset() { e.Reset(); cnt = 0; } } }
Paul is the COO of kwiboo ltd and has more than 20 years IT consultancy experience. He has consulted for a number of blue chip companies and has been exposed to the folowing sectors: Utilities, Telecommunications, Insurance, Media, Investment Banking, Leisure, Legal, CRM, Pharmaceuticals, Interactive Gaming, Mobile Communications, Online Services.
Paul is the COO and co-founder of kwiboo (http://www.kwiboo.com/) and is also the creator of GeekZilla.
Comments
Chris Roberts
said:
I like what you've done here Paul. You're showing the first 10 items, but say you had 100 items. How do you show the next 10 and then the next 10 and so on (basically paging)?
Akash Dwivedi
said:
Good one. you did really good work. I searched for this at many places but got solution at your site.
Akash Dwivedi
said:
Good one. you did really good work. I searched for this at many places but got solution at your site.
udeeb
said:
this really works but I have one question.
Once I get the top 10 from dataview, is there any way that I can change the existing dataview to only contain those 10 records, so that I can sort and change those remaining data only?
Thanks for your help...
phayman
said:
udeeb,
I'd be inclined to use Generics or Linq to do this now. Check the following article:
http://www.geekzilla.co.uk/View3B286690-73F9-41B2-A882-DDAD91647B7F.htm
Paul
Srinivasan V
said:
Hi Paul,
Thanks for the code. It helps a lot.
Good work Paul.
by
Srini
said:
You have done realy great job thanks for posting this article
Sonny Eugenio
said:
The code is really great it's exactly what I need. Thanks Paul for sharing it with us.
marcusorjames
said:
If anyone wants this in VB:
Imports System
Imports System.Data
Imports System.Web.Security
Imports System.Collections
''' <summary>
''' Summary description for FilterRows
''' </summary>
Public Class FilterRows
Implements IEnumerable Dim _dataView As New DataView Dim _rowsToShow As Integer Public Sub New(DataView As DataView, rowsToShow As Integer) Me.RowsToShow = rowsToShow Me.DataView = DataView End Sub Public Property RowsToShow As Integer Get Return _rowsToShow End Get Set(value As Integer) _rowsToShow = value End Set End Property Public Property DataView As DataView Get Return _dataView End Get Set(value As DataView) _dataView = value End Set End Property Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator Return New PageOfData(Me.DataView.GetEnumerator(), Me.RowsToShow) End Function
Private Class PageOfData Implements IEnumerator Dim _e As IEnumerator Dim _cnt As Integer = 0 Dim _rowsToShow As Integer Public Sub New(e As IEnumerator, rowsToShow As Integer) Me.RowsToShow = rowsToShow Me.E = e End Sub Public ReadOnly Property Current As Object Implements System.Collections.IEnumerator.Current Get Return E.Current End Get End Property Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext 'If we've hit out limit return false If _cnt >= RowsToShow Then Return False End If 'Track the current row _cnt = _cnt + 1 Return E.MoveNext() End Function Public Sub Reset() Implements System.Collections.IEnumerator.Reset E.Reset() _cnt = 0 End Sub Public Property RowsToShow As Integer Get Return _rowsToShow End Get Set(value As Integer) _rowsToShow = value End Set End Property Public Property E As IEnumerator Get Return _e End Get Set(value As IEnumerator) _e = value End Set End Property End Class
End Class