CSLA .NET

From Rockford Lhotka's Expert C# 2005 and VB 2005 Business Objects books

Welcome to CSLA .NET Sign in | Join | Help
in Search

Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

Last post 09-01-2007, 7:48 AM by RockfordLhotka. 6 replies.
Sort Posts: Previous Next
  •  04-12-2007, 1:53 PM 13802

    Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    In a web app, I needed paging and sorting to be done on a number of pages.  I wanted something generic and looked at SortedBindingList and FilteredBindingList.  After reading a couple of Rocky's posts and looking at the FilteredBindingList, it became apparent that using FilteredBindingList focuses on individual items rather than the state of the list.  Therefore, I went a little different route.

    I implemented a class that derives from IList<T> and also implements IReportTotalRowCount where T is your business object  This little class first sorts the list handed to it and then applies the filtering based on the passed in SelectObjectArgs. 

    *** I believe that different grids will pass back differing information for the Sort Expression.  The grid I am using (telerik) is clean, but I've seen others (Intersoft) that like to get cute if I remember correctly.  Just a note of caution.  Also, you could make this more generic to recognize when paging is not being requested by looking at SelectObjectArgs and operate accordingly.

    The best part is the wiring of the SelectObjects event off the Csla Datasource control. Assuming I have a list of Customer objects (ReadOnly, BusinessObject, etc.) and a function that retrieves the Customer objects for the page (from db, session, viewstate, etc), the code looks like this:

    CSLADataSource_SelectObject( object sender, Csla.Web.SelectObjectArgs e)
    {
       e.BusinessObject = new SortedAndPagedBindingList< Customer >(GetCustomerCollection(), e);
    }

    Now for the code:


    /// <summary>
    /// SortedAndPagedBindingList:  This class is responsible for taking a List of 'TBase' and returning
    /// a subset of items that are sorted and paged according to the Csla Datasource control. This control also
    /// implements IReportTotalRowCount which is required to support paging within Csla.
    /// </summary>
    /// <typeparam name="TBase">The collection of Csla objects being sorted and paged</typeparam>
    public class SortedAndPagedBindingList<TBase> : List<TBase>, Csla.Core.IReportTotalRowCount
    {
        /// <summary>
        /// _totalRowCount:  This retains the count of the initial list (as opposed to the trimmed down
        /// result set. Used for paging purposes.
        /// </summary>
        private int _totalRowCount = -1;

        /// <summary>
        /// Constructor:  This constructor builds out object list according to the Csla request.
        /// </summary>
        /// <param name="collection">The source list of all items to be considered.</param>
        /// <param name="args">The paging and sorting parameters used against the incoming list</param>
        public SortedAndPagedBindingList(IList<TBase> collection, Csla.Web.SelectObjectArgs args)
            : base(args.MaximumRows)
        {
            // first, grab the total row count for reporting through the IReportTotalRowCount
            _totalRowCount = collection.Count;

            // next, we'll sort the list if requested.

            Csla.SortedBindingList<TBase> sortedList = new Csla.SortedBindingList<TBase>(collection);

            if (args.SortExpression.Length > 0)
                sortedList.ApplySort(args.SortExpression, args.SortDirection);

            // finally, we'll add the page of items requested by SelectObjectArgs
            if (args.StartRowIndex > sortedList.Count - 1)
                return;

            int rowIndex = args.StartRowIndex;

            while ((rowIndex - args.StartRowIndex) < args.MaximumRows && rowIndex < sortedList.Count)
                this.Add(sortedList[rowIndex++]);

        }

     

        #region IReportTotalRowCount Members

        /// <summary>
        /// TotalRowCount - this property returns the total row count for the initial list that passed to the
        /// constructor.
        /// </summary>
        int Csla.Core.IReportTotalRowCount.TotalRowCount
        {
            get { return _totalRowCount; }
        }

        #endregion


    }

  •  07-24-2007, 2:08 PM 16374 in reply to 13802

    Re: Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    Thanks, Mongo.  That worked great.  This was a real headache before I found your code.

    Marc

  •  07-29-2007, 9:59 PM 16490 in reply to 16374

    Re: Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    Thanks, but why e.StartRowIndex and e.MaxRows always = 1 in my test? Any thought?

    I have to modified like this to make it works:

    public class SortedAndPagedBindingList<TBase> : List<TBase>, Csla.Core.IReportTotalRowCount
    {
        private int _totalRowCount = -1;

        public SortedAndPagedBindingList(IList<TBase> collection,  Csla.Web.SelectObjectArgs args)
            : base(collection.count)
        {
            _totalRowCount = collection.Count;

            Csla.SortedBindingList<TBase> sortedList = new Csla.SortedBindingList<TBase>(collection);

            if (args.SortExpression.Length > 0)
                sortedList.ApplySort(args.SortProperty, args.SortDirection);

                   int i;

            for (i=0;i<collection.count;i++)
                this.Add(sortedListIdea [I]);

        }

     

  •  08-05-2007, 7:36 AM 16668 in reply to 13802

    Re: Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    Hi,

    I became a member jst to say thankx...i'v just work with csla.net for a few months...so im fairly new and your code helped me heapz :-)

    Shaheem.
  •  08-30-2007, 3:08 PM 17199 in reply to 16668

    Re: Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    Mongo,

    Thanks for the code. I have implemented it with a slight change (to fix an issue I ran into).

    I modified it from

            if (args.SortExpression.Length > 0)
                sortedList.ApplySort(args.SortExpression, args.SortDirection);

    to

            if (args.SortProperty.Length > 0)
                sortedList.ApplySort(args.SortProperty, args.SortDirection);

    since ApplySort takes the SortProperty as a first argument and not the Expression. It seems like the correct thing to do, do you agree?

    I utilized this in conjunction with telerik's RadGrid control, and ran into an issue sorting in ascending order on a date. I probed further, and looked at SelectObjectArgs.cs. I don't know if it is specific to this control (the telerik RadGrid control), but when I was attempting to sort ascending, the _sortProperty would be set to "PropertyName ASC" which is not a valid property on my object (it should of been "PropertyName"). I changed it from the following:

        public SelectObjectArgs(System.Web.UI.DataSourceSelectArguments args)
        {

          _startRowIndex = args.StartRowIndex;
          _maximumRows = args.MaximumRows;
          _retrieveTotalRowCount = args.RetrieveTotalRowCount;

          _sortExpression = args.SortExpression;
          if (!(string.IsNullOrEmpty(_sortBLOCKED EXPRESSION)
          {
            if (_sortExpression.Length >= 5 &&
              _sortExpression.Substring(_sortExpression.Length - 5) == " DESC")
            {
              _sortProperty = _sortExpression.Substring(0, _sortExpression.Length - 5);
              _sortDirection = ListSortDirection.Descending;

            }
            else
            {
              _sortProperty = args.SortExpression;
              _sortDirection = ListSortDirection.Ascending;
            }
          }
        }

    to

        public SelectObjectArgs(System.Web.UI.DataSourceSelectArguments args)
        {

          _startRowIndex = args.StartRowIndex;
          _maximumRows = args.MaximumRows;
          _retrieveTotalRowCount = args.RetrieveTotalRowCount;

          _sortExpression = args.SortExpression;
          if (!(string.IsNullOrEmpty(_sortBLOCKED EXPRESSION)
          {
            if (_sortExpression.Length >= 5 &&
              _sortExpression.Substring(_sortExpression.Length - 5) == " DESC")
            {
              _sortProperty = _sortExpression.Substring(0, _sortExpression.Length - 5);
              _sortDirection = ListSortDirection.Descending;

            }
            else if (_sortExpression.Length >= 4 &&
                _sortExpression.Substring(_sortExpression.Length - 4) == " ASC")
            {
                _sortProperty = _sortExpression.Substring(0, _sortExpression.Length - 4);
                _sortDirection = ListSortDirection.Ascending;
            }
            else
            {
              _sortProperty = args.SortExpression;
              _sortDirection = ListSortDirection.Ascending;
            }
          }
        }

     

    After making these two changes, presto. Dates now sorted in both ascending and descending order correctly. I don't know if the telerik control is to blame for passing in the addtional " ASC" for the sort expression or if other controls do the same. I figured I would post it here as a potential bug in CSLA in case someone else runs into it. I'll test it with a different Grid (probably the Microsoft Gridview) and see if the sort expression includes the " ASC" or not. I'll post my results.

     

    Mike

  •  08-30-2007, 3:30 PM 17200 in reply to 17199

    Re: Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    Following up, it appears like the Microsoft GridView does in fact only pass in "PropertyName" instead of "PropertyName ASC" like the telerik RadGrid does for the SortExpression.

    Regardless, would the change in SelectObjectArgs I proposed in the previous post make sense?

    As for the change I made to Mongo's code, I needed to also add a check for null as well.

            if (args.SortProperty != null && args.SortProperty.Length > 0)
                sortedList.ApplySort(args.SortProperty, args.SortDirection);

    Are there any potential issues with either of these changes?

    Thanks,

    Mike

  •  09-01-2007, 7:48 AM 17220 in reply to 17200

    Re: Fun with CSLA Databinding, paging and sorting along with IReportTotalRowCount

    Those seem like good changes, I'll add this to the wish list.
    Rocky
View as RSS news feed in XML

Please contact Magenic for your .NET consulting and CSLA .NET mentoring needs.
Please consider making a donation to help support the ongoing development of CSLA .NET.

Make donation through PayPal - it's fast, free and secure!
Why donate?
Powered by Community Server, by Telligent Systems