Click here to Skip to main content
Licence CPOL
First Posted 8 Dec 2008
Views 25,336
Downloads 260
Bookmarked 26 times

GridView:Sorting & Paging Using Generics And Nullable Datatype Function Of C# GetValueOrDefault()

By | 8 Dec 2008 | Article
This article demonstrate the Sorting mechanism for Nullable datatype when used with IList collection.

Introduction

The idea behind writing this article is to overcome the problem related to sorting of collection having null values in it. Recently I was working with GridView control and I was using generic collection list as a data source to it. While resolving this problem alone I developed a good piece of functionality which I do feel will help most of you in your development activity.

Features Available

The feature incorporated in the GridView are as follows:

  • Used C#'s Generics
  • Used Nullable Datatype
  • Used Generics Collection IList To Bind GridView. 
  • Sorting Of Generics Collection IList Using IComparer Interface .
  • Applied Nullable Datatype function GetValueOrDefault for Sort Operation On Nullable Datafield.
  • Fully Tested Concurrent Sorting And Paging Operation In GridView.

    Problem Statement

    I had nullable value field data type in my database table. So I used nullable datatype of C# in my asp.net code. Doing so I encountered sorting failure problem with IComparer. After some research and development I came up with the solution. I used GetValueOrDefault() to resolve this. How I applied this to my solution is demonstrated below.

    Consider Database table schema as:
    Column DataType Nullable Values
    CountryID Int No
    CountryName String No
    CountryTradeCode Int Yes

     

    Implement IComparer:Business Entity Class Country

    In below class we have three field as discussed. In this we have m_CountryTradeCode as nullable data type. I was facing problem sorting nullable data type. So I got a workaround for this as shown here.

     case CountryComparer.CountryComparisonType.CountryTradeCode:
                        
    return this.m_CountryTradeCode.GetValueOrDefault().CompareTo(rhs.m_CountryTradeCode.GetValueOrDefault());
    
    An important aspect to know about IComparer is that it operates on a complete Class Object and it knows about the object elements while IComparable operates only on elements of the object. The complete class is given below.
    public class Country
        {
            private int m_CountryID = int.MinValue;
            private string m_CountryName = string.Empty;
            private int? m_CountryTradeCode = null;
    
            public Country()
            {
    
            }
            public Country(int countryID)
            {
                m_CountryID = countryID;
    
            }
            public Country(int countryID, string countryName, int? countryTradeCode)
                : this(countryID)
            {
                m_CountryName = countryName;
                m_CountryTradeCode = countryTradeCode;
            }
            public int CountryID
            {
                get { return m_CountryID; }
                set { m_CountryID = value; }
            }
            public int? CountryTradeCode
            {
                get { return m_CountryTradeCode; }
                set { m_CountryTradeCode = value; }
            }
            public string CountryName
            {
                get { return m_CountryName; }
                set { m_CountryName = value; }
            }
            public int CompareTo(Country rhs, Country.CountryComparer.CountryComparisonType which)
            {
                switch (which)
                {
                    case CountryComparer.CountryComparisonType.CountryID:
                        return this.m_CountryID.CompareTo(rhs.m_CountryID);
                    case CountryComparer.CountryComparisonType.CountryName:
                        return this.m_CountryName.CompareTo(rhs.m_CountryName);
                    case CountryComparer.CountryComparisonType.CountryTradeCode:
                        return this.m_CountryTradeCode.
    GetValueOrDefault().CompareTo(rhs.m_CountryTradeCode.GetValueOrDefault());
    
                }
                return 0;
            }
            public class CountryComparer : IComparer< Country >
            {
                public enum CountryComparisonType
                {
                    CountryID,
                    CountryName,
                    CountryTradeCode,
                    NULL
                }
                private CountryComparisonType _whichComparison;
                private Utility.SortOrder _sortDirection;
                public CountryComparisonType WhichComparison
                {
                    get { return _whichComparison; }
                    set { _whichComparison = value; }
                }
                public int Compare(Country lhs, Country rhs)
                {
                    if (SortDirection == Utility.SortOrder.Asc)
                        return lhs.CompareTo(rhs, WhichComparison);
                    else
                        return rhs.CompareTo(lhs, WhichComparison);
                }
                public bool Equals(Country lhs, Country rhs)
                {
                    return this.Compare(lhs, rhs) == 0;
                }
                public int GetHashCode(Country e)
                {
                    return e.GetHashCode();
                }
                public Utility.SortOrder SortDirection
                {
                    get { return _sortDirection; }
                    set { _sortDirection = value; }
                }
            }
        }

    Populate Collection List With Country Object

    One can get this data from database using datareader and can populate this collection list as given below.For ready to go solution I have not used database and have hardcoded the values for understanding purpose. If you notice there is null fields in the objects that is been added as record in Collection List.The important challenge here is to sort this collection list having null value field. The nullable type is only applied to value type. As null reference is not assigned to value type,C# nullable datatype provide this feature.For eg. int a=null; is not allowed in C#. This is overcome by nullable datatype and the above example can be re written for nullable type as int? a = null;

     private IList<Country> GetCountryList()
            {
                IList < Country > countryList = new List < Country >();
                countryList.Add(new Country(1, "United States Of America", 100001));
                countryList.Add(new Country(2, "Africa", null));
                countryList.Add(new Country(3, "India", null));
                countryList.Add(new Country(4, "Singapore", 100004));
                countryList.Add(new Country(5, "Newzealand", 100005));
                countryList.Add(new Country(6, "United Kingdom", 100006));
                countryList.Add(new Country(7, "Australia", 100007));
                countryList.Add(new Country(8, "China", 100008));
                countryList.Add(new Country(9, "Malaysia", null));
                countryList.Add(new Country(10, "Germany", 100011));
                countryList.Add(new Country(11, "France", 100009));
                countryList.Add(new Country(12, "United States Of Soviet Russia", null));
                return countryList;
            }
    

    C# Generics Method:Bind GridView Control

           private void BindGrid < T >(T list)
            {
                gridCountry.DataSource = list;
                gridCountry.DataBind();
            }
    

    Sort Event Logic

    private void SortCountryList(Country.CountryComparer.CountryComparisonType sortExpression)
            {
                List < Country > countryList = (List < Country >)GetCountryList();
                Country.CountryComparer countryComparer = new Country.CountryComparer();
                if (Country.CountryComparer.CountryComparisonType.NULL != sortExpression)
                {
                    if (sortExpression == SortColumn)
                    {
                        if (SortDirection == Utility.SortOrder.Asc)
                        {
                            SortDirection = Utility.SortOrder.Desc;
                        }
                        else
                        {
                            SortDirection = Utility.SortOrder.Asc;
                        }
                    }
                    else
                    {
                        SortDirection = Utility.SortOrder.Asc;
                    }
                    SortColumn = sortExpression;
                }
                countryComparer.WhichComparison = SortColumn;
                countryComparer.SortDirection = SortDirection;
                countryList.Sort(countryComparer);
                CountryDataSource = countryList;
            }

    Concurrent paging And Sorting Operation On Grid

    Contrary to what the title suggests,paging and sort operation here is not happening at the same time.The flow of the program suggests that the sorted order of a given column in a grid has to be maintained when paging operation is done.That means paging is carried out on sorted List.For this I used Viewstate to maintain the current operation.

                  private Country.CountryComparer.CountryComparisonType SortColumn
            {
                get { return (Country.CountryComparer.CountryComparisonType)ViewState["SORT_EXP"]; }
                set { ViewState["SORT_EXP"] = value; }
            }
               
            private Utility.SortOrder SortDirection
            {
                get { return (Utility.SortOrder)ViewState["SORT_ORDER"]; }
                set { ViewState["SORT_ORDER"] = value; }
            }
           

    Initially the list is loaded with current sort order and sort direction.

      protected void Page_Load(object sender, EventArgs e)
            {
                try
                {
                    if (IsPostBack == false)
                    {
                        SortColumn = Country.CountryComparer.CountryComparisonType.CountryID;
                        SortDirection = Utility.SortOrder.Asc;
                        LoadCountryList();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            private void LoadCountryList()
            {
                SortCountryList(Country.CountryComparer.CountryComparisonType.NULL);
            }
    

    This is called on page change event on sorted List.

      private void PagingCountryList()
            {
                SortCountryList(Country.CountryComparer.CountryComparisonType.NULL);
            }

    One can download the code and can check the code for more understanding and usage purpose.

    Conclusion

    Hope I met the expectations of the reader and also please vote for this article ,this will help me to understand the quality I put in. Any suggestion and advice are most welcome. Looking forward for your feedback.

    References

    Icomparer:Reference: http://www.ondotnet.com/pub/a/dotnet/excerpt/progcsharp4_ch09-04/index.html?page=5

    History

    First Cut-Initial Draft: 8-Dec-2008

  • License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    About the Author

    santosh poojari

    Technical Lead

    India India

    Member

    He is presently working as tech arch in one of the leading IT company.He has total 9 years of experience in C#.net. He is a B.E graduate in Computers from Bombay University.
     
    Most of his experiences are in designing architect for end to end solutions. His interest areas are WCF,Spring.net,Architecture- Model View Presenter,UML,Webservice,Performance Engineering/tuning,Design patterns,Generics,Enterprise Library,Regular expressions,Silverlight and WWF.

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board. (secure sign-in)
     
    Search this forum  
     FAQ
        Noise  Layout  Per page   
      Refresh
    GeneralNice work Pinmemberstevetcp18:58 11 Jan '09  
    GeneralRe: Nice work Pinmembersantosh poojari23:23 14 Jan '09  
    Thanks atleast someone understood the implementation rather than pointing out my small mistakes..My purpose is served.
     
    Happy Coding
    "San"
     

     

    General[Message Deleted] PinmemberVladimir_V11:36 8 Dec '08  
    GeneralRe: My vote of 1 PinmemberBAIJUMAX17:12 8 Dec '08  
    GeneralImage conveys lot more than words PinmemberGautam Sharma18:11 8 Dec '08  
    GeneralMessage Automatically Removed PinmemberCPAV10:20 8 Dec '08  
    GeneralDude, Africa is not a country Pinmemberbinarycheese3:24 8 Dec '08  
    GeneralRe: Dude, Africa is not a country Pinmemberthund3rstruck15:28 8 Dec '08  
    GeneralRe: Dude, Africa is not a country Pinmemberdougnlamb9:39 10 Jul '09  

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    Permalink | Advertise | Privacy | Mobile
    Web01 | 2.5.120529.1 | Last Updated 8 Dec 2008
    Article Copyright 2008 by santosh poojari
    Everything else Copyright © CodeProject, 1999-2012
    Terms of Use
    Layout: fixed | fluid