【问题标题】:Reverse-sorting a Listview (with Comparer class)对 Listview 进行反向排序(使用 Comparer 类)
【发布时间】:2009-10-07 16:01:22
【问题描述】:

我有一个链接到 Datapager 的两列 ListView。 ListView 列出了特定目录中特定类型的所有文件,因此数据源是 FileInfo 类型的 ArrayList。因此,我必须创建一个 Comparer 类以在 ArrayList.Sort 方法中使用。

FileInfoComparer.vb:

Imports System.IO

Friend Class FileInfoDateComparer
 Implements IComparer

 Public Overridable Overloads Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
  Dim oX As FileInfo = CType(x, FileInfo)
  Dim oY As FileInfo = CType(y, FileInfo)
  Return oX.LastWriteTime.CompareTo(oY.LastWriteTime)
 End Function
End Class

Friend Class FileInfoNameComparer
 Implements IComparer

 Public Overridable Overloads Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
  Dim oX As FileInfo = CType(x, FileInfo)
  Dim oY As FileInfo = CType(y, FileInfo)
  Return oX.Name.CompareTo(oY.Name)
 End Function
End Class

GenerateSortedArray 子:

 Private Sub GenerateSortedArray(ByVal SortColumn As String, ByVal SortDirection As String)
  Dim dirInfo As New DirectoryInfo(Server.MapPath(AppSettings.Item("ContentDir")))
  Dim FileArrayList As New ArrayList(dirInfo.GetFiles("*.msg", SearchOption.TopDirectoryOnly))

  With FileArrayList
   .TrimToSize()
   Select Case SortColumn
    Case "Name"
     .Sort(New FileInfoNameComparer)
    Case Else
     .Sort(New FileInfoDateComparer)
   End Select
  End With

ListView_Sorting:

  Session("SortColumn") = e.SortExpression
  Session("SortDirection") = e.SortDirection

  Call GenerateSortedArray(e.SortExpression, DBNull.Value.ToString)

这一切都很好,但是,我不知道如何反转排序。从代码中可以看出,我已经确定了排序方向,但是我不知道如何使用它来反转排序。

有什么想法吗?

【问题讨论】:

  • 3 个出色且几乎相同的解决方案,而且简单到连我都能理解。向鲁本斯和斯科特道歉——我希望我能分给你一份公平的战利品。
  • 进一步思考,我真的应该将两个比较器类合二为一,并传递列名......

标签: asp.net vb.net sorting dataview icomparer


【解决方案1】:

我通常会这样做:

Friend Class FileInfoDateComparer
 Implements IComparer

    Private _sortOrder As System.Windows.Forms.SortOrder

    Public Sub New(ByVal sortOrder As System.Windows.Forms.SortOrder)
        _sortOrder = sortOrder
    End Sub

    Public Overridable Overloads Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
       Dim oX As FileInfo = CType(x, FileInfo)
       Dim oY As FileInfo = CType(y, FileInfo)
       Dim result As Integer = oX.LastWriteTime.CompareTo(oY.LastWriteTime)
       If _sortOrder = System.Windows.Forms.SortOrder.Descending Then
           ' we want the reverse sort order, so we "reverse" the result '
           result = result * -1
       End If
       Return result
 End Function
End Class

如果您不想使用 System.Windows.Forms.SortOrder,您可以滚动您自己的 SortOrder 枚举。我通常更喜欢枚举而不是布尔值,因为您会在代码中清楚地说明值的含义。比较这两个:

Dim comparer As New FileInfoDateComparer(True)
Dim comparer As New FileInfoDateComparer(SortOrder.Descending)

【讨论】:

  • 我实际上使用了 SqlClient.SortOrder (毕竟它是一个网络应用程序!),但是你因为建议枚举而获得了大奖。简单而整洁。
【解决方案2】:

你的Comparer类是否包含一个名为SortAscending之类的布尔成员变量,并允许通过构造函数指定此值。

例如,您的 FileInfoDateComparer 类将类似于以下(未经测试的)代码:

Class FileInfoDateComparer
 Implements IComparer

  Private _SortAscending As Boolean = True

  Public Sub New(sortAscending As Boolean)
    _SortAscending = sortAscending
  End Sub

  ...
End Class

有了这些,剩下的就是在调用 CompareTo IF SortAscending = False 之前“交换”oX 和 oY 值。

Public Overridable Overloads Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
  Dim oX As FileInfo = CType(x, FileInfo)
  Dim oY As FileInfo = CType(y, FileInfo)

  If _SortAscending = False Then
    Dim temp As FileInfo = oX
    oX = oY
    oY = temp
  End If

  Return oX.LastWriteTime.CompareTo(oY.LastWriteTime)
End Function

应该这样做!仅供参考,上面的代码是即兴输入的,所以可能存在语法错误,但这个概念是合理的——我自己在过去的项目中使用过很多次。

最后一条评论 - 如果您使用的是 .NET 3.5+,您可以使用 LINQ to Objects 语法,而不必创建自己的 Comparer 类,如果您愿意的话...

快乐编程...

【讨论】:

  • 我的 cmets 和 Ruben 一样,我遇到了一个清晰的比较器示例,它是有意义的。 LINQ 目前完全未知,但显然在我的待办事项列表中(还有很多其他内容!)。
  • CJM,查看这篇文章以获得对 LINQ 的简要介绍(带有 VB 和 C# 示例):4guysfromrolla.com/articles/021109-1.aspx FYI,以下是 LINQ 使一切变得简单和简洁的方式:dirInfo.GetFiles("*.msg ", SearchOption.TopDirectoryOnly).OrderBy(Function(f) f.LastWriteTime)
【解决方案3】:

您可以通过FileInfoDateComparer 发送 SortDirectory;接收“DESC”值,您可以将返回值乘以 -1;

// sorry, C# version:

class FileInfoDateComparer
{
    private bool ascendingOrder = true;
    public FileInfoDateComparer(bool ascendingOrder)
    {
        this.sortOrder = sortOrder;
    }

    ... int Compare(object x, object y)
    {
        //...
        return
            oX.LastWriteTime.CompareTo(oY.LastWriteTime) * 
            (ascendingOrder ? 1: -1);
    }

}

你没有说你的框架版本,但考虑使用Reverse()Linq扩展方法。

【讨论】:

  • 我正在使用 3.5,所以 LINQ 已经在使用中,但目前它只是向未知领域迈进了一步 - 但我很感谢你的建议。
猜你喜欢
  • 2016-12-27
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 2017-06-05
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多