Sorting pada Generics Datasource

Di .NET Frameworks 2.0 terdapat Generics List yang dapat digunakan sebagai datasource. Dibandingkan dengan dataset, generics lebih ringan dan cepat. Pada dataset terdapat fitur2 mubadzir yang tidak dibutuhkan. Dengan menggunakan List kita dapat definisikan sesuai dengan kebutuhan.

Karena ringan dan sederhana, datasource menggunakan List tidak dapat diurutkan dengan mengeset Allow Sorting pada GridView dan memasukkan SortExpression begitu saja. Berikut salah satu cara untuk dapat menggunakan List sebagai datasource yang dapat diurutkan.

Pertama buat class SortableList yang di-inherit dari System.Collection.Generics.List dan PropertyComparer

VB.NET

Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Reflection

Public Class SortableList(Of T)
    Inherits List(Of T)
    Private _propertyName As String
    Private _ascending As Boolean

    Public Sub New()

    End Sub

    Public Sub New(ByVal collection As IEnumerable(Of T))
        Me.AddRange(collection)
    End Sub

    Public Overloads Sub Sort(ByVal propertyName As String, (ByVal ascending As Boolean)

        'Flip the properties if the parameters are the same
        If (_propertyName = propertyName And _ascending = ascending) Then
            _ascending = Not ascending
            'Else, new properties are set with the new values
        Else
            _propertyName = propertyName
            _ascending = ascending
        End If

        Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T))
        Dim propertyDesc As PropertyDescriptor = properties.Find(propertyName, True)

        ' Apply and set the sort, if items to sort
        Dim pc As PropertyComparer(Of T)
        If _ascending Then
            pc = New PropertyComparer(Of T)(propertyName, ListSortDirection.Ascending)
        Else
            pc = New PropertyComparer(Of T)(propertyName, ListSortDirection.Descending)
        End If
        Me.Sort(pc)
    End Sub
End Class

Public Class PropertyComparer(Of T)
    Implements IComparer(Of T)

    Private ReadOnly _propertyInfo As System.Reflection.PropertyInfo
    Private ReadOnly _sortDirection As ListSortDirection
    ' Constructor
    Public Sub New(ByVal propertyToSort As String, ByVal direction As ListSortDirection)
        _sortDirection = direction
        _propertyInfo = GetType(T).GetProperty(propertyToSort, _
           System.Reflection.BindingFlags.Instance Or _
           System.Reflection.BindingFlags.Public Or _
           System.Reflection.BindingFlags.FlattenHierarchy Or _
           System.Reflection.BindingFlags.IgnoreCase)
    End Sub
    ' IComparer(Of T) interface
    Public Function Compare(ByVal x As T, ByVal y As T) _
       As Integer _
         Implements IComparer(Of T).Compare
        Dim xValue As Object = _propertyInfo.GetValue(x, Nothing)
        Dim yValue As Object = _propertyInfo.GetValue(y, Nothing)
        If _sortDirection = ListSortDirection.Ascending Then
           Return System.Collections.Comparer.Default.Compare( _
            xValue, yValue)
        Else
           Return System.Collections.Comparer.Default.Compare( _
               yValue, xValue)
        End If
    End Function
End Class

Sebagai contoh dibuat class sebagai representasi tabel di database sebagai berikut:

Public Class Contact
    Private _Name As String
    Private _Address As String
    Private _Phone As String
    Public Sub New(ByVal Name As String, ByVal Address As String, ByVal Phone As String)
        _Name = Name
        _Address = Address
        _Phone = Phone
    End Sub
    Public Property Name() As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property
    Public Property Address() As String
        Get
            Return _Address
        End Get
        Set(ByVal value As String)
            _Address = value
        End Set
    End Property
    Public Property Telp() As String
        Get
            Return _Telp
        End Get
        Set(ByVal value As String)
            _Telp = value
        End Set
    End Property
End Class


 Contoh pada code behind 

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
    Dim list As SortableList(Of Contact) = BuildList()
    Cache.Insert("Contact", list, Nothing, _
        System.Web.Caching.Cache.NoAbsoluteExpiration, _
        System.Web.Caching.Cache.NoSlidingExpiration, _
        System.Web.Caching.CacheItemPriority.High, _
        Nothing)
    contactsGridView.DataSource = list
    UsersGridView.DataBind()
End Sub

Protected Sub contactsGridView_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles contactsGridView.PageIndexChanging
    Dim list As SortableList(Of Contact) = CType(Cache("Users"), SortableList(Of Contact))
    UsersGridView.PageIndex = e.NewPageIndex
    UsersGridView.DataSource = list
    UsersGridView.DataBind()
End Sub

Protected Sub contactsGridView_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs) Handles contactsGridView.Sorting
    Dim list As SortableList(Of Contact) = CType(Cache("Users"), SortableList(Of Contact))
    list.Sort(e.SortExpression, CBool(e.SortDirection = SortDirection.Ascending))
    'Add the sorted collection back to the cache
    Cache.Insert("Users", list, Nothing, _
        System.Web.Caching.Cache.NoAbsoluteExpiration, _
        System.Web.Caching.Cache.NoSlidingExpiration, _
        System.Web.Caching.CacheItemPriority.High, _
        Nothing)
       
    UsersGridView.DataSource = list
    UsersGridView.DataBind()
End Sub 

Share this post: | | | |
Published Monday, April 30, 2007 9:56 AM by cahnom
Filed under: ,

Comments

# re: Sorting pada Generics Datasource

Monday, April 30, 2007 12:17 PM by asuhanto

Menggunakan reflection juga biasanya menambah overhead karena CLR hrs secara runtime mesti membaca assembly manifest untuk mengetahui property mana yang mesti di-sort.

Alternatif lain jika Anda tidak mau menggunakan reflection, mungkin bisa membatasi T dengan constraints where T implements suatu interface yang Anda definisikan sendiri. Interface tersebut mesti mendefinisikan property-property mana yang 'sortable'. Tentu saja solusi ini tidak berlaku secara generic karena dengan membatasi T implements suatu interface berarti program Anda bind terhadap solusi domain tertentu.

But, anyway... that's an alternatif.

# re: Sorting pada Generics Datasource

Monday, April 30, 2007 1:52 PM by basir

kayanya bos AK perna mention ttg sorting pake reflection.

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems