不使用StrCmpLogicalW或shlwapi.dll以数字和字母顺序(如Windows资源管理器)对数组进行排序 - ASP.NET VB

时间:2010-11-12 14:34:19

标签: asp.net vb.net sorting

我创建了一个StrCmpLogicalW / shlwapi.dll的分拣机。不幸的是,它会导致部分信任环境出错。我非常需要一个不使用'shlwapi.dll'或StrCmpLogicalW并且以相同方式工作的解决方案。

请HELPPPPP!

这是导致错误的分拣机。

Public Class nvSorter
    Implements IComparer(Of String)

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

    Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare
        Return StrCmpLogicalW(x, y)
    End Function

End Class

1 个答案:

答案 0 :(得分:1)

这应该有效:

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Filenames() As String = New String() {"0", "1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "3", "4", "5", "6", "7", "8", "9"}
        Array.Sort(Filenames, New CustomComparer)
        MessageBox.Show(String.Join(",", Filenames))
    End Sub
End Class

Public Class CustomComparer
    Implements IComparer(Of String)

    Private Position As Integer
    Private Order As Integer = 1

    Public Sub New(Optional ByVal Ascending As Boolean = True)
        If Not Ascending Then
            Order = -1
        End If
    End Sub

    Private Shared Function EmptyText(ByVal s As String) As Boolean
        Return String.Empty.Equals(s)
    End Function

    Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare
        Dim res1 As New List(Of String)(System.Text.RegularExpressions.Regex.Split(x, "(\d+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
        Dim res2 As New List(Of String)(System.Text.RegularExpressions.Regex.Split(y, "(\d+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
        res1.RemoveAll(AddressOf EmptyText)
        res2.RemoveAll(AddressOf EmptyText)
        Position = 0

        For Each xstr As String In res1
            If res2.Count > Position Then
                If Not IsNumeric(xstr) AndAlso Not IsNumeric(res2(Position)) Then
                    Dim intresult As Integer = String.Compare(xstr, res2(Position), True)
                    If intresult <> 0 Then
                        Return intresult * Order
                    Else
                        Position += 1
                    End If
                ElseIf IsNumeric(xstr) And Not IsNumeric(res2(Position)) Then
                    Return -1 * Order
                ElseIf Not IsNumeric(xstr) And IsNumeric(res2(Position)) Then
                    Return 1 * Order
                ElseIf IsNumeric(xstr) And IsNumeric(res2(Position)) Then
                    Dim res As Integer = Decimal.Compare(Decimal.Parse(xstr), Decimal.Parse(res2(Position)))
                    If res = 0 Then
                        Position += 1
                    Else
                        Return res * Order
                    End If
                End If
            Else
                Return -1 * Order
            End If
        Next

        Return 1 * Order
    End Function
End Class

"0", "1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "3", "4", "5", "6", "7", "8", "9"的上述排序示例的结果是:

alt text