Sorting - Who's responsibility?

Sorting - Who's responsibility?

Old forum URL: forums.lhotka.net/forums/t/8345.aspx


Kevin Fairclough posted on Wednesday, January 13, 2010

Hi,

We are currently experiencing a problem where Undo/Cancel doesn't retain the order for child collections, as the deleted items are put back at the end of the collection.  This has lead us to wonder what layer should be responsible for sorting these collections.

Currently we are sorting child collections via our database layer such as "created_on desc", but this breaks on undo in the UI.  We have a lot of child collections on our BO's so if the UI is responsible for sorting, the UI dev has to remember to wrap all the collections.

So where should we do the sorting???

Should these collections be wrapped and sorted in the BO?  How?
Should the ViewModel wrap and sort them?

TIA
Kevin

Csla 3.8 - WPF

RockfordLhotka replied on Wednesday, January 13, 2010

In almost all cases sorting is a UI concern.

Rarely is there a business requirement for sorting, though that can happen in batch processing sceanrios like invoice posting routines.

But the fact that sorting is a UI concern doesn't mean people don't frequently sort at the database level - in fact it is required in cases where paging is also used. But sorting at the database level is often a very efficient way to address the UI requirement - but the requirement still lives at the UI.

And generally speaking, if your UI allows different sorts, it is unlikely (again, unless you use paging) taht you'd go back to the database just to resort the items. That'd be inefficient, so usually the sort is just changed right there on the client.

Normally WPF would just do this for you, but as has been discussed on numerous other threads, CSLA collections inherit from BindingList<T>, not ObservableCollection<T>, so the auto-sorting doesn't work. In another thread this morning though, someone mentioned that Infragistics has a datagrid that does work with BindingList collections - something I think WPF should have done to start with...

CSLA 4 will address this issue by having two sets of collection base classes, and the default set will work with WPF (everything but Windows Forms actually).

Kevin Fairclough replied on Wednesday, January 13, 2010

Thanks for the quick reply Smile [:)]

Our particular problem only happens because of the undo.  The user cannot sort the listbox contents and they are retrieved in created_on order, newest first.  Therefore our standard behaviour of adding new items puts them at the beginning, they are always in order until an undo operation.

I think in this case the BO should be responsible for the sorting?  Should the BO expose another list that is sorted and used for binding?

TIA
Kevin


rsbaker0 replied on Wednesday, January 13, 2010

Here's a thought... CSLA includes a class called SortedBindingList that can provide a sorted view into any IList.

Perhaps you could create one of these and bind it to your list rather than the actual list provided by the BO.

vschaak replied on Thursday, January 14, 2010

Hello,

hm, I'm not that sure, that sorting should be a UI concern, almost exclusivly.

I give an example: let your app have a grid with a list of certain objects (say employee) presented to the user. He/she clicks (as used to) on a column header, let's say "age" property. Ok, asume it works as expected. But now he clicks on "print this employee list". What does he expect to be printed and most important: in what ranking! I'd guess in the same sorting as he sorted the grid before. Unfortunatly one has to do that work separatly to the objectlist that is handled to the report-engine.

So, I won't call that a requirement to the UI and it's controls (grid in this case), but to the underlying object, whereas the action is triggered by the UI. In that way similar to the delete functionality (marking the row header and pressing DEL). Triggered by the UI, but definitly done/represented by the object.

Just my 2c

Best wishes

Volker

Kevin Fairclough replied on Thursday, January 14, 2010

In my root BO I plan to do the following:

private static PropertyInfo<ChildList> ChildListProperty = RegisterProperty(new PropertyInfo<ChildList>("ChildList", PropertyNames.ChildList));
private ChildList _ChildList
{
    get { return GetProperty(ChildListProperty); }
    set { SetProperty(ChildListProperty, value); }
}

[NonSerialized]
[NotUndoable]
private SortedBindingList<ChildItem> _childSorted;
public SortedBindingList<ChildItem> ChildList
{
    get
    {
    if (_
childSorted== null)
        _
childSorted= new SortedBindingList<ChildItem>(ChildList);
    _
childSorted.ApplySort("CreatedOn", ListSortDirection.Descending);
    return _
childSorted;             
    }
}

The fact I have to do this because of the Undo is annoying.

Will the binding to the UI still work, with regard to edits etc?

TIA
Kevin



rsbaker0 replied on Thursday, January 14, 2010

The sorted binding list holds references to all the object in the source list, so in theory this should work.

The only possibly missing piece (and you'll just have to try it without doing this first) might be that you would override UndoChangesComplete() in your root BO and call ApplySort on your _childSorted member.

Incidentally, some Grid controls, like the DevExpress XtraGrid, might take care of all this automatically in the UI without you having to do any of this, so it's possible that to some degree you're being forced into it by the choice of UI controls.

ajj3085 replied on Thursday, January 14, 2010

I don't understand why you simply don't do that in the UI.  After the user elects the undo, just call apply sort.

Kevin Fairclough replied on Friday, January 15, 2010

Well this is the real question.

If the UI shouldn't re-sort the collection then the sorting code shouldn't be inside the UI, No?.  The undo appends deleted items when restoring them hence I have to messy up my BO with wrappers around all my (non UI sortable) collections.

Kevin

Copyright (c) Marimer LLC