VB BindingSource SupportsSorting 为假。为什么?

VB BindingSource SupportsSorting is false. Why?

我一直在网上四处游荡,试图解决这个问题,但我做不到。

我有一个 BindingSource,我 .add 来自 .GetFiles 的一堆 FileInfo

当我单步执行时,BindingSourceSupportsSorting 属性 是 False。我不明白为什么。

我尝试将 BindingSource.DataSource 设置为 BindingList,而不是一个一个地添加每个 FileInfo,但是底层列表仍然是 IList 类型。

这是我的代码:

 If Directory.Exists(configPath) Then
            For Each foundFile As FileInfo In New DirectoryInfo(configPath).GetFiles("*.csv", SearchOption.TopDirectoryOnly)
                If foundFile.Length >= My.Settings.scanFileSizeThreshold Then

                    scansBindingSource.Add(foundFile)
                End If
            Next
        Else

我只想做这样的事情:

scansBindingList.Sort = "LastWriteTime Desc"

并让 DataGridView 中的数据按上次写入时间排序。这可能吗?谢谢!

BindingList不支持排序。 MSDN 上也有 BindingSource:

If the data source is not an IBindingList, the SupportsSorting property always returns false.

您可以让 NET 按照 LastWriteTime 的顺序将文件传送给您,这样您就不必对它们进行排序(也可以摆脱循环):

Dim theFiles = New DirectoryInfo(fpath).EnumerateFiles(fmask, SearchOption.TopDirectoryOnly).
            Where(Function(f) f.Length > szMin).
            OrderByDescending(Function(s) s.LastWriteTime)

dgv2.DataSource = New BindingSource(theFiles, Nothing)

NET会将文件排序,排除不匹配的文件,而不是将它们发送给您只是为了测试和排除。结果是绑定源可以直接使用的 IEnumerable

如果您希望能够添加到这些列表并对其进行排序,请使用 List(Of FileInfo) 进行存储和排序,然后使用 BindingSource 进行 adding/deleting。

Private filesBS As BindingSource
Private FilesList As List(Of FileInfo)
...
FilesList = New DirectoryInfo(...).EnumerateFiles("*.csv", SearchOption.AllDirectories).
               Where(Function(f) f.Length > MinSize).
               OrderByDescending(Function(q) q.LastWriteTime).
               ToList()

filesBS = New BindingSource(FilesList, Nothing)
dgv2.DataSource = filesBS

文件查询和之前一样,我只是添加了ToList();然后将其用于 BindingSource。如果您通过 BindingSource 添加和删除项目,它们将显示在 collection 和 DGV 中。

filesBS.RemoveAt(0)
filesBS.Add(newItem)

沉闷的部分是排序,因为它必须完成 'manually'(也就是说 DGV 不会/不能这样做)并且因为 FileInfo 有太多的属性。一种排序方法是使用扩展方法,就像在查询中所做的那样:

' sort by file size
If fileSortOrder = SortOrder.Ascending Then
    FilesList = FilesList.OrderBy(Function(f) f.Length).ToList()
Else
    FilesList = FilesList.OrderByDescending(Function(f) f.Length).ToList()
End If
filesBS = New BindingSource(FilesList, Nothing)
' ToDo: toggle fileSortOrder like below

dgv2.DataSource = filesBS

请注意,由于 FilesList collection 已重新创建,您还需要重建 BindingSource。也可以使用Sort方法:

FilesList.Sort(AddressOf FileInfoSizeCompare)
dgv2.Refresh()
...
Private fileSortOrder As SortOrder = SortOrder.Ascending
Private Function FileInfoSizeCompare(x As FileInfo, y As FileInfo) As Int32
    Dim sortReverser As Int32 = If(fileSortOrder = SortOrder.Ascending, 1, -1)
    Dim ret As Int32 = 0
    If x.Length < y.Length Then ret = -1
    If x.Length > y.Length Then ret = 1

    Return (ret * sortReverser)
End Function

在这种情况下,由于没有重新创建列表,您只需刷新控件即可重绘内容。对于您希望作为排序依据的每个 column/property,您将需要不同的方法。无论使用哪种方法,如果您从 ColumnHeaderMouseClick 事件调用方法,它将像 DGV 可以对 DataSource.

进行排序时那样工作

如果我要使用第二个版本,我可能会将 Sort 方法放在 class 中,这样 a) 我可以重用它们,b) 从表单中获取所有代码。