VB BindingSource SupportsSorting 为假。为什么?
VB BindingSource SupportsSorting is false. Why?
我一直在网上四处游荡,试图解决这个问题,但我做不到。
我有一个 BindingSource
,我 .add
来自 .GetFiles
的一堆 FileInfo
。
当我单步执行时,BindingSource
的 SupportsSorting
属性 是 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) 从表单中获取所有代码。
我一直在网上四处游荡,试图解决这个问题,但我做不到。
我有一个 BindingSource
,我 .add
来自 .GetFiles
的一堆 FileInfo
。
当我单步执行时,BindingSource
的 SupportsSorting
属性 是 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) 从表单中获取所有代码。