我正在寻找一些关于处理此问题的最佳方法的建议。
我有一个大约200个“功能”的列表,它们在组合框中列出。当用户从列表中选择“函数”时,我需要返回functionID(整数)。
我知道这可以通过将数据集绑定到组合框的键和值来轻松完成,我只是不确定填充数据集的最佳方法。
我觉得我现在这样做的方式非常错综复杂:
我目前有一个txt文件作为嵌入式资源,我写入临时目录,然后我使用以下代码读取该文本文件,并通过设置组合框的数据源和显示成员来填充该框。它通过实现System.Collections.IList的自定义类来实现。
我已粘贴以下代码。我想简化它的原因是我不喜欢将文本文件写入磁盘,因为有时它会失败。
我正在寻找一种方法来填充我的组合框并返回我的ID,而无需向用户的临时文件夹写任何内容。
我愿意改变嵌入资源和/或代码的格式。
fnlist.txt的格式目前如下。
索引,函数名称,ID
索引仅用于排序(保持NONE在底部,而未知函数在顶部),我认为并非严格要求。
#Region "Function lookup"
Dim path As String = System.IO.Path.GetTempPath
Dim _objFnXtef As New clsFunctionXref(path & "fnList.txt")
Private Sub populate_list()
functionlist.DataSource = _objFnXtef
functionlist.DisplayMember = "StrFunction"
End Sub 'Populates the function list
Function get_index(ByVal fnid As Integer)
Dim iLookupNumber As Integer = fnid
Dim tmpFnInfo As New clsFunctionInfo
Dim iReturnIdx As Integer = -1
If iLookupNumber <> 0 Then
tmpFnInfo.IFunctionNumber = iLookupNumber
iReturnIdx = _objFnXtef.IndexOf(tmpFnInfo)
If iReturnIdx <> -1 Then
Return iReturnIdx - 1
Else
Return get_index(9999)
End If
End If
Return 0
End Function 'Returns index of specified function number
#End Region 'All function list functions
以下是用户更改下拉列表时的代码:
Private Sub functionlist_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles functionlist.SelectedIndexChanged
Dim iReturnFuctionID As Integer = 0
Dim tmpFnInfo As New clsFunctionInfo
tmpFnInfo = _objFnXtef(functionlist.SelectedIndex)
iReturnFuctionID = tmpFnInfo.IFunctionNumber
Func = (iReturnFuctionID)
End Sub
以下是支持班:
Imports Microsoft.VisualBasic.FileIO
Public Class clsFunctionInfo
Private _idxFunction As Integer
Public Property IdxFunction() As Integer
Get
Return _idxFunction
End Get
Set(ByVal value As Integer)
_idxFunction = value
End Set
End Property
Private _strFunction As String
Public Property StrFunction() As String
Get
Return _strFunction
End Get
Set(ByVal value As String)
_strFunction = value
End Set
End Property
Private _iFunctionNumber As Integer
Public Property IFunctionNumber() As Integer
Get
Return _iFunctionNumber
End Get
Set(ByVal value As Integer)
_iFunctionNumber = value
End Set
End Property
End Class
Public Class clsFunctionXref
Implements System.Collections.IList
Private _colFunctionInfo As New Collection
Private _filePath As String
Public Property FilePath() As String
Get
Return _filePath
End Get
Set(ByVal value As String)
_filePath = value
End Set
End Property
Public Sub New(ByVal filename As String)
_filePath = filename
Dim _idx As Integer = 1
Dim fields As String()
Dim delimiter As String = ","
Dim iFnx As Integer
Using parser As New TextFieldParser(filename)
parser.SetDelimiters(delimiter)
While Not parser.EndOfData
' Read in the fields for the current line
fields = parser.ReadFields()
Try
iFnx = Convert.ToInt16(fields(0).ToString)
Catch ex As Exception
MessageBox.Show("Error reading file. " & ex.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
Dim objFunction As New clsFunctionInfo
objFunction.IdxFunction = _idx
objFunction.IFunctionNumber = iFnx
objFunction.StrFunction = fields(1).ToString
Me.Add(objFunction)
_idx += 1
End While
End Using
End Sub
Public Function Add(ByVal value As Object) As Integer Implements System.Collections.IList.Add
If _colFunctionInfo.Contains(value.IFunctionNumber.ToString) Then
SyncLock Me.SyncRoot
_colFunctionInfo.Remove(value.IFunctionNumber.ToString)
End SyncLock
ReIndex()
End If
SyncLock Me.SyncRoot
_colFunctionInfo.Add(value, value.IFunctionNumber.ToString)
End SyncLock
End Function
Public Sub Clear() Implements System.Collections.IList.Clear
SyncLock Me.SyncRoot
_colFunctionInfo.Clear()
End SyncLock
End Sub
Public Function Contains(ByVal value As Object) As Boolean Implements System.Collections.IList.Contains
If _colFunctionInfo.Contains(value.IFunctionNumber.ToString) Then
Return True
Else
Return False
End If
End Function
Public ReadOnly Property Count() As Integer Implements System.Collections.ICollection.Count
Get
Return _colFunctionInfo.Count
End Get
End Property
Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.IList.IsReadOnly
Get
Return False
End Get
End Property
Public Sub Remove(ByVal value As Object) Implements System.Collections.IList.Remove
If _colFunctionInfo.Contains(value.IFunctionNumber.ToString) Then
SyncLock Me.SyncRoot
_colFunctionInfo.Remove(value.IFunctionNumber.ToString)
End SyncLock
ReIndex()
End If
End Sub
Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return _colFunctionInfo.GetEnumerator
End Function
Public Sub Insert(ByVal index As Integer, ByVal value As Object) Implements System.Collections.IList.Insert
SyncLock Me.SyncRoot
If _colFunctionInfo.Contains(value.IFunctionNumber.ToString) Then
_colFunctionInfo.Remove(value.IFunctionNumber.ToString)
End If
If index < _colFunctionInfo.Count Then
_colFunctionInfo.Add(value, value.IFunctionNumber.ToString, index - 1)
Else
_colFunctionInfo.Add(value, value.IFunctionNumber.ToString)
End If
End SyncLock
ReIndex()
End Sub
Public Sub RemoveAt(ByVal index As Integer) Implements System.Collections.IList.RemoveAt
SyncLock Me.SyncRoot
If _colFunctionInfo.Count <= index And index > 0 Then
_colFunctionInfo.Remove(index)
End If
End SyncLock
ReIndex()
End Sub
Private Sub ReIndex()
SyncLock Me.SyncRoot
Dim iReIndex As Integer = 1
Dim colTemp As New Collection
For Each obj As clsFunctionInfo In _colFunctionInfo
obj.IdxFunction = iReIndex
colTemp.Add(obj, obj.IFunctionNumber)
iReIndex += 1
Next
_colFunctionInfo.Clear()
For Each obj1 As clsFunctionInfo In colTemp
_colFunctionInfo.Add(obj1, obj1.IFunctionNumber.ToString)
Next
colTemp.Clear()
End SyncLock
End Sub
Public ReadOnly Property IsSynchronized() As Boolean Implements System.Collections.ICollection.IsSynchronized
Get
Return True
End Get
End Property
Public ReadOnly Property SyncRoot() As Object Implements System.Collections.ICollection.SyncRoot
Get
Dim _syncRoot As New Object
Return _syncRoot
End Get
End Property
Public ReadOnly Property IsFixedSize() As Boolean Implements System.Collections.IList.IsFixedSize
Get
Return False
End Get
End Property
Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer) Implements System.Collections.ICollection.CopyTo
For Each obj As clsFunctionInfo In _colFunctionInfo
array(index) = obj
index += 1
Next
End Sub
Public Function IndexOf(ByVal value As Object) As Integer Implements System.Collections.IList.IndexOf
SyncLock Me.SyncRoot
Dim tmpFnInfo As New clsFunctionInfo
Dim tmpFunctionNumber As Integer
Dim tmpidx As Integer = -1
tmpFnInfo = DirectCast(value, clsFunctionInfo)
tmpFunctionNumber = tmpFnInfo.IFunctionNumber
For Each obj In _colFunctionInfo
tmpFnInfo = DirectCast(obj, clsFunctionInfo)
If tmpFunctionNumber = tmpFnInfo.IFunctionNumber Then
tmpidx = tmpFnInfo.IdxFunction
Exit For
End If
Next
Return tmpidx
End SyncLock
End Function
Default Public Property Item(ByVal index As Integer) As Object Implements System.Collections.IList.Item
Get
index += 1
Return _colFunctionInfo(index)
End Get
Set(ByVal value As Object)
End Set
End Property
End Class
对不起,这太长了,但我知道有人在这里有一些关于如何处理这个问题的好建议,因为我在缠绕它时遇到了一些麻烦。我想我已经主演了太久了。
答案 0 :(得分:1)
由于您将文本文件作为嵌入式资源,因此您可以从那里打开文件流,而无需将其写入磁盘。 ResourceReader类应该可以帮到你。