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;
        }
    }
}

Author Paul Hayman

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)?

31/Mar/2007 08:38 AM

Akash Dwivedi said:

Good one. you did really good work. I searched for this at many places but got solution at your site.

16/May/2007 15:25 PM

Akash Dwivedi said:

Good one. you did really good work. I searched for this at many places but got solution at your site.

16/May/2007 15:25 PM

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...

28/Jul/2008 21:36 PM

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

29/Jul/2008 09:06 AM

Srinivasan V said:

Hi Paul,

    Thanks for the code. It helps a lot.

Good work Paul.

by

Srini

15/Jul/2009 11:48 AM

said:

You have done realy great job thanks for posting this article

30/Dec/2009 11:41 AM

Sonny Eugenio said:

The code is really great it's exactly what I need. Thanks Paul for sharing it with us.

30/Jan/2010 16:39 PM

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

20/Sep/2011 15:46 PM

Add Comment

Name
Comment
 

Your comment has been received and will be shown once it passes moderation.