这是我关于 SO 的第一个问题。如果我在问的方式上犯了错误,请原谅我,如果是这样,请让我不要。
我目前正在尝试以编程方式对 ComboBox 中的项目进行排序。
我正在填充 CB 的数据现在处理如下: - 从数据库(sqllite)查询 - 用结果填充数据表 - 从组合框填充项目范围
由于数据同时包含数字和不包含数字的字符串,因此普通的排序函数(SQL、DataTable、ComboBox)无法完成这项工作。(图片)
到目前为止:我现在的方法是混合类似主题的答案。我尝试使用 DataTable 中的辅助列来分隔字符串/整数中的给定值,然后我想根据这两个辅助值的内容进行排序。
代码:
(请关注第一个“尝试”块。我也复制了其余代码,因为我认为它解释了我的意图)。
' This function adds items to the referred ComboBox "cb" based on the data from the given DataTable "tbl".
' "tbl" in every case consists of one column named "value":
' -The number of rows varies.
' -The column type is undefined (varies too).
' -Data can be like: "Sicherungsscheibe", "156.4", "780", "M10" (Examples!)
' These are values which are describing attributes like "length", "material", "thread", "diameter", "type".
Sub AddItemsOfTableToComboBox(ByRef cb As ComboBox, tbl As DataTable)
' Use temporary DataTable and copy each value from within the source column to "tempTB",
' beacause a type conversion on already source bound columns is not possible.
Dim tempDT As New DataTable("tempDT")
Dim DataSet1 As New DataSet
DataSet1.Tables.Add(tempDT)
tempDT = tbl.Clone()
tempDT.Columns("value").DataType = GetType(String)
For Each row As DataRow In tbl.Rows
tempDT.ImportRow(row)
Next
' Fill first temporary column "Scol1". Check first char (only) for a letter. This approach should be sufficient for values like "M12".
Try
' This one works, and gives the desired feedback: It copies every string from the column "value" to "Scol1" which are beginning with "B".
tempDT.Columns.Add(New DataColumn("Scol1", GetType(String)) With {.Expression = "iif (substring(value,1,1) like 'B',substring(value,1,len(value)),'else')"})
' Same as above, beacuse case insensitive.
tempDT.Columns.Add(New DataColumn("Scol1", GetType(String)) With {.Expression = "iif (substring(value,1,1) like 'B',substring(value,1,len(value)),'else')"})
' This one works. Here I want to copy every non digit char. But however, the feedback is always 'else'.
tempDT.Columns.Add(New DataColumn("Scol1", GetType(String)) With {.Expression = "iif (substring(value,1,1) like '\D',substring(value,1,len(value)),'else')"})
' Doenst work: '[A-Z]' is invalid.
tempDT.Columns.Add(New DataColumn("Scol1", GetType(String)) With {.Expression = "iif (substring(value,1,1) like '[A-Z]',substring(value,1,len(value)),'else')"})
' This one works. But feedback is always 'else'.
tempDT.Columns.Add(New DataColumn("Scol1", GetType(String)) With {.Expression = "iif (substring(value,1,1) like '[[]A-Z[]]',substring(value,1,len(value)),'else')"})
Catch ex As Exception
MsgBox(ex.Message)
End Try
' Fill second temp column "Scol2"
Try
tempDT.Columns.Add(New DataColumn("Scol2", GetType(Integer)) With {.Expression = "Convert(iif (substring(value,2,len(value)) like '\d',substring(value,2,len(value)),'0'), 'System.Int32')"})
Catch ex As Exception
MsgBox(ex.Message)
End Try
'Dim View As New DataView(tbl)
'View.Sort = "Scol1,Scol2"
'View.Table = DataSet1.Tables("tempDT")
' Here I would had convert "tempDT" into "tbl" again somehow.
With cb
.Items.Clear()
Dim items = tbl.AsEnumerable().Select(Function(d) DirectCast(d(0).ToString(), Object)).ToArray()
If items.Length > 0 Then
.Parent.Enabled = True
.Items.AddRange(items)
.Sorted = True
Else
' Disable corresponding Panel(parent) if for some reason there are no items to fill the ComboBox with.
' (f.e. if there's a recorded class but no corresponding subclass, or
' there's a recorded class/category without any parts referred to it.)
.Parent.Enabled = False
End If
End With
End Sub
我希望定义一组字符的模式能够正常工作。到目前为止,我对使用 lambda 表达式、处理 DataTables/Views 或使用正则表达式不是很熟悉/没有经验。
...知道我在哪里犯错吗?