Tip: Secondary column sorting in listview

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Tip: Secondary column sorting in listview

Louis Sumberg-2
There's nothing really new in this post except for the packaging, so to
speak.

One thing that's bothered me for awhile is the lack of secondary sorting in
listviews.  That is, the ability to click on a column and have the listview
sort its rows by the clicked-upon column AND another column.  For example,
in PersonalMoney, if you click on the description column, you probably want
the list sorted by description AND date.  Currently though, it just sorts by
description.  If you have more than one transaction with the same
description, successive clicks on the description column will keep the rows
sorted by description, but the order of rows with the same description will
change.

It turns out that secondary sorting can be done, though there are some
constraints.  The trick is to set the getContentsBlock, getTextBlock, and
sortBlock aspects of each column.  Continuing with the PersonalMoney
example, here's the before and after for the description column in the
transactions listview:

Before: Primary sorting only:
getContentsBlock: [:transaction | transaction description]
getTextBlock:  BasicListAbstract
sortBlock: SortedCollection

After: Primary and secondary sorting:
getContentsBlock: nil
getTextBlock: [:transaction | transaction description]
sortBlock: [:a :b | a description = b description
   ifTrue: [a date < b date]
   ifFalse: [a description < b description]]

In the first case (Before), the getContentsBlock ensures that there's a
string value in each cell of the column, in which case the default
getTextBlock and default sortBlock are sufficient to sort the column.

In the second case (After), no getContentsBlock is specified, so each cell
in the column contains a transaction object.  This means a getTextBlock is
needed to provide a string value to display and a sortBlock is needed for
sorting.  In this case, since both a and b in the sortBlock are
transactions, not strings, the sortBlock can refer to the transactions'
aspects in determining how to sort.  If two transactions have the same
description, then sort them by date, else sort by description.

Naturally, it was after I figured this out that I found a few posts in DSDN
relating to this (9/29/01), and found at least one view in the image that
uses secondary sorting.  That view is the CHB, where the upper right
listview (showing selectors) has secondary sorting in the first two columns.
Take a look, and while you're at it, check out the customDrawBlock for the
third column to see how loose methods are colored.

-- Louis