0

I would like to sort entries in a List(Of IO.FileInfo)

1. Filename number One.txt
10. Filename number 10.txt
11. Filename number 11.txt
12. Filename number 12.txt
...
19. Filename number 19.txt
2. Filename number Two.txt
20. Filename number 20.txt
21. Filename number 21.txt
...

as they appear 'naturally' sorted by the leading numbers in windows file explorer:
1./2./...10./11./12...19./20./21.

I use the following code to fill a List(Of IO.FileInfo)

Dim diStartDir As IO.DirectoryInfo = New IO.DirectoryInfo("C:\Temp")
Dim ListOfMatchingFiles As New List(Of IO.FileInfo)
For Each FileName In diStartDir.GetFiles("*.txt", IO.SearchOption.AllDirectories)
    ListOfMatchingFiles.Add(Filename)
Next

ListOfMatchingFiles.Sort() '<-- naturally sort is the tricky part...

In the Visual Studio Designer, I don't get any error. If I debug this code, the last command .Sort() results in the error:

Fehler beim Vergleichen von zwei Elementen im Array.
An error occurred while comparing two elements.

I'm not able to get a working solution from the examples found with ICompare or LINQ.

Could you help me please with VB.NET code that allows to naturally sort my List(Of IO.FileInfo) by (file)name?

PeterCo
  • 910
  • 2
  • 20
  • 36
  • http://stackoverflow.com/questions/248603/natural-sort-order-in-c-sharp or http://stackoverflow.com/questions/3099581/sorting-an-array-of-folder-names-like-windows-explorer-numerically-and-alphabet – Tim Schmelter Aug 15 '14 at 14:30
  • Thank you for the URL's, @Tim Schmelter. Which one of the linked solutions provides VB.NET code working with a List(Of IO.FileInfo)? – PeterCo Aug 15 '14 at 15:28

1 Answers1

3

I think, I've found a solution. If you want to sort the List(Of IO.FileInfo) by the filename only - without the full path - add the following Comparer Class.
Rename Comparer_FileInfo_Name_NaturalSort to whatever you like:

Public Class Comparer_FileInfo_Name_NaturalSort
    Implements IComparer(Of IO.FileInfo)

    Declare Unicode Function StrCmpLogicalW Lib "shlwapi.dll" (ByVal s1 As String, ByVal s2 As String) As Integer

    Public Function Compare(fi1 As IO.FileInfo, fi2 As IO.FileInfo) As Integer Implements IComparer(Of IO.FileInfo).Compare
        Return StrCmpLogicalW(fi1.Name, fi2.Name)
    End Function
End Class



If you like to sort by full path including the filename, replace the RETURN-line with

    Return StrCmpLogicalW(fi1.FullName, fi2.FullName)



Then you can sort your List(Of IO.FileInfo) with the following command:

ListOfMatchingFiles.Sort(New Comparer_FileInfo_Name_NaturalSort)



I'm not sure, why many examples includes lines like

<Security.SuppressUnmanagedCodeSecurity>

or

<Runtime.InteropServices.DllImport("shlwapi.dll", CharSet:=Runtime.InteropServices.CharSet.Unicode, ExactSpelling:=True)>

and what exactly is the difference to the above Declare Unicode Function

PeterCo
  • 910
  • 2
  • 20
  • 36