Proper way to initialize ShellListView.SortShellPropertyKey?

Shell for WPF Forum

The latest build of this product (v2019.1 build 0685) was released 5 months ago, which was before this thread was created.
Posted 21 days ago by rex hui
Version: 19.1.0685
Avatar

How do I set the initial value of the SortShellPropertyKey property?

For example, if I want to have the ShellListView to be sorted by the "Size" when first loaded, how do I do that? How do I obtain the IShellProperty objects to be used for this at the start? I tried overriding the WindowsShellService class to obtain that and then setting to it but it seems to be very slow, probably because it is after the list has been already rendered?

Thanks,

Comments (8)

Posted 20 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rex,

Each Windows shell folder has its own list of properties that are available to be listed in columns.  We query the shell to see which to show.  Then we choose the properties that are commonly displayed by default. 

Windows shell uses a special PROPERTYKEY structure for its property keys that is a pair of a known FormatID Guid and an integer PropID.  Unfortunately our implementation of this native structure is internal.  The values for the Size column are listed here.

You can call our WindowsShellService.CreateProperties method using ShellPropertyRequestKind.DefaultColumns to get the default columns for a shell object.  So for instance you could call this method for the Desktop shell object at app startup, look through the IShellProperty results and when you find the Size column's Key, store that globally, and later set that to ShellListView.SortShellPropertyKey since it's always the same.


Actipro Software Support

Posted 20 days ago by rex hui
Avatar

Thanks. I tried and it sets the sort column correctly as indicated by the arrow on the column header but the items are not actually sorted. It seems it is still always sorted by the Name property.

Posted 19 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rex,

Thanks for reporting this.  Please try downloading a new preview build at the same URL we gave you before.  That has some code updates in it that hopefully resolve this.  Kindly report back the results.


Actipro Software Support

Posted 19 days ago by rex hui
Avatar

Thanks. This works.

However, I just realized that the Shell code is rather unefficient.

If I set the initial path to "C:\Windows\System32\" which has about 3000 items.

Without setting the SortShellPropertyKey to "Size" property, the listview takes less than a second to load but setting it will make it take over 5 seconds to load. Freezing the UI for 5 seconds is obviously not acceptable especially during startup.

I think the Shell sorting implementation is rather unefficient. It can easily be reproduced by running the ShellListView Intro quickstart and navigate to "C:\Windows\System32\" and sort on different columns.

Do you have any suggestions?

Posted 18 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rex,

We will have to do some in-depth debugging to see what the root cause is and how we can improve it.  It will probably take several days to dig into this, but we'll reply back when we have some more information.


Actipro Software Support

Posted 18 days ago by rex hui
Avatar

Sure. Thank you!

Posted 14 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rex,

After some researching via performance profiling, we found that 55% of the time is spent in the List<T>.Sort call tree.  A lot of that is where the comparer is calling into the shell to get the property values.  Since the default List<T> sort algorithm calls to get a value several times for each object, and each one of the related shell API calls takes some time, we could possibly improve that with some caching of the property values, at least for that particular overall Sort call session.

Another 42% of the time was spent in logic that reorders the ObservableCollection<T> after the list sort is complete, so that the order of the main ObservableCollection<T> matches the final sorted list results.  This involves a lot of calls to ObservableCollection.MoveItem.  Each one of those calls raises an event that is handled by the control so it can reposition any visible TreeListViewItems and ensure that the selection is maintained.  We can look into this some more to see if anything can be improved here, but I'm not sure.  Doing a "reset" collection change notification instead would be fast, but would lose the selection.

We worked to add property value caching as described above and obtained a 700% increase in sorting speed when testing in C:\Windows\System32.  It went from over 5 seconds to under a second.  We also tried some other optimizations within the ObservableCollection<T> update logic and slightly improved speed a bit further there too.

The updates will be in the next maintenance release.


Actipro Software Support

Posted 14 days ago by rex hui
Avatar

Excellent! Thank you very much!

Add Comment

Please log in to a validated account to post comments.