我一直在试图解决这个问题的互联网周围巡航,但我不能。
我有BindingSource
.add
FileInfo
来自.GetFiles
的{{1}}。
当我单步执行时,BindingSource
的{{1}}属性为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
将DataGridView中的数据按上次写入时间排序。这可能吗?谢谢!
答案 0 :(得分:0)
BindingList
不支持排序。同样在MSDN上有这个BindingSource
:
如果数据源不是IBindingList,则SupportsSorting属性始终返回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
进行添加/删除。
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
添加和删除项目,它们将显示在集合和DGV中。
filesBS.RemoveAt(0)
filesBS.Add(newItem)
沉闷的部分是排序,因为它必须“手动”完成(也就是说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
集合,因此您还需要重建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
在这种情况下,由于未重新创建列表,您只需刷新控件即可重绘内容。对于要排序的每个列/属性,您将需要不同的方法。无论使用哪种方法,如果您从ColumnHeaderMouseClick
事件调用方法,它都会像DGV对DataSource
进行排序时那样工作。
如果我要使用第二个版本,我可能会将Sort方法放在一个类中,以便a)我可以重用它们,然后b)从表单中获取所有代码。