我正在寻找有关处理此问题的最佳方法的一些建议。
我有一个组合框中列出的大约 200 个“功能”的列表。当用户从列表中选择“函数”时,我需要返回函数 ID(整数)。
我知道这可以通过将数据集绑定到组合框的键和值来轻松完成,我只是不确定填充数据集的最佳方法。
我觉得我目前这样做的方式非常复杂:
我目前有一个 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
很抱歉,这太长了,但我知道这里有人对如何处理这个问题有一些很好的建议,因为我在解决这个问题时遇到了一些麻烦。我想我已经主演它太久了。