PBDR.COM

About   -   Contact   -   Purchase   -   Search   -   What's New

 
 
Listview Custom Sort
PBDelta uses a variety of controls for the UI and in the File Selection window I use the Treeview and Listview objects. The combination gives an explorer style navigation for selecting files. I used the out of the box sort for the list view columns, however two of the columns where not "string" data but a size and a date column, when the out of the box sort was used it sorted them as string not as the original data type and was not particularly useful.

I wanted to make the columns sort using their underlying data types,  but I did not want to keep two copies of the data around and then sort the rows manually based on the seconds copy of the data, so I set about coding the "sort" event on the list view. The sort event works a little bit like a comparator on a list, it gets called by PB and asks you to tell PB if item a is before, after or identical item b.

I coded this up and it worked just fine, however on a large list I noticed the performance when populating the list was slow. Even once populated the performance of the text columns was not as good as it was previously using the in built PB routines.

Some testing revealed that the complete sort process was firing every time I added an item to the list, which makes sense but was a bit of a performance hit. As my data was loaded in the correct order in the first place I did not even need the sort!

To improve matter I switched off the custom sort property so there was no sort by default and put a check in the columnclicked event to see which column was clicked, if it was a basic string data type I called the standard PB function as follows:

this.Sort( Ascending!, column )

Then if it was a complex data type I called the custom routine:

this.Sort( UserDefinedSort!, column )

Finally I added code to the sort event which used the 3 parameter version of the GetItem command. This version allows you to get the value from a list view column as follows:

this.GetItem( index1, column, ls_Item1 )
this.GetItem( index2, column, ls_Item2 )

ls_Item1 now contains the string value of the column, I just convert that into the original data type and then can perform the comparison as normal:

ll_Item1 = Long( ls_Item1 )
ll_Item2 = Long(  ls_Item2 )
IF ll_Item1 > ll_Item2 THEN RETURN 1
IF ll_Item1 < ll_Item2 THEN RETURN -1
 

Top of Page

Legal Notice

Ken Howe 2011