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
