“记住”过去条目的方法

时间:2015-06-29 16:41:58

标签: .net vb.net combobox stack queue

我在VB中构建的应用程序的一部分具有终端功能,我想为它添加功能,以便按时间顺序记住过去的命令,类似于windosw终端的工作方式。

简而言之,我希望您能够在文本区域聚焦时按向上箭头,并能够循环显示先前输入的命令列表。

我有两个关于如何做到这一点的想法:

  1. 一个组合框,当你按Enter键时,读取combobox.text中的任何内容,无论是新输入的命令还是旧选择的命令。然后将该命令添加到组合框的项目中,以便您可以向上滚动并再次找到它。

  2. 只是一个文本框,当按下向上箭头时,循环浏览一些存储的队列并相应地设置文本。这需要第二个队列来记住循环命令并替换它们,对吗?

  3. 是否有任何内置的Visual Basic结构会更好,或者有更好的方法吗?

    感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

听起来你正在寻找像最近使用的列表这样的东西。

你对ComboBox的看法通常是正确的做法。要使用TextBox执行建议,主要会导致...... ComboBox

考虑:

  • 是否区分大小写? FooBar是否匹配fooBar
  • 堆栈(或队列)不是正确的工具,因为如果它们使用列表中索引4的内容,则没有简单的方法将该项目从#4移动到#1。
  • 要使用ComboBox作为UI选择器,您希望使用可用作绑定源的内容。

这是一个新生的MRU课程:

Public Class MRUList

    Private myList As BindingList(Of String)

    Public ReadOnly Property DataList As BindingList(Of String)
        Get
            Return myList '.Select(Function(f) f.Value).ToList
        End Get
    End Property

    Private myCapacity As Integer

    Public Sub New(capacity As Integer)
        myCapacity = capacity
        myList = New BindingList(Of String)
    End Sub

    Public Overloads Sub Add(item As String)

        Dim ndx As Integer = IndexOfKey(item)

        If ndx >= 0 Then
            myList.RemoveAt(ndx)
        End If

        myList.Insert(0, item)

        If myList.Count > myCapacity Then
            myList.RemoveAt(myList.Count - 1)
        End If
    End Sub

    ' case insensitive search
    Private Function IndexOfKey(s As String) As Integer

        Return myList.ToList.FindIndex(Function(f) f.Equals(s,
                   StringComparison.InvariantCultureIgnoreCase))

    End Function

End Class
  • 当他们选择现有项目时,它会从那里移动到列表的顶部。
  • 不区分大小写," Able"匹配" ABLE"。但它是案例感知的:如果/当他们再次输入项时,它会使用新的套管。所以如果" ZIggy"如果他们输入" Ziggy"则在插槽3的列表中。正确地,他们旧的一个被删除,新的一个使用。
  • 有一个容量限制器,所以你不会得到荒谬的长列表。当列表太长时,旧项目将被删除。
  • 它是根据BindingList(Of String)构建的,因此您可以将其绑定到ListboxComboBox

列表管理非常浪费。每次我们在myList(0)处插入一个新项目时,.NET必须移动并跳转底层数组。理想的集合类型是LinkedList,但它不能作为绑定源使用,我不怀疑你将存储1000个项目。

用法:

Private myMRU As New MRUList(8)
...
' bind to CBO in form_load:
cboMRU.DataSource = myMRU.DataList

随着事物被添加到列表中,它们将自动出现在列表中。当用户进行选择时

Private Sub cboMRU_Leave(sender As Object, e As EventArgs) Handles cboMRU.Leave
    If cboMRU.Text.Length = 0 Then Exit Sub

    Dim thisCmd As String = cboMRU.Text
    myMRU.Add(thisCmd)
    cboMRU.Text = ""

End Sub

我使用了Leave事件,因为他们可以从列表中选择从列表中选择一个项目。在检查新项目与现有项目时,您的代码不需要执行任何操作,Add方法会为您执行此操作。

enter image description here

在左侧,我输入了4个项目,Delta是最后一个项目。接下来,我正确输入了Able。该课程删除了旧课程,并将新课程作为具有新拼写的MRU浮动到顶部。

由于这些对您的代码意味着什么,因此在事件中使用thisCmd无论它们是什么。对于更复杂的事情,也许他们键入的内容只是其他内容的关键或标记,请在BindingList(of TokenItem)类中使用MRU

答案 1 :(得分:0)

比队列更好的是数组。队列只允许顺序访问,在您出列队列后,您出列的对象会丢失"丢失"。如果你想保存它并且也在将来的会话中,你可以使用文件,例如cookie或我喜欢的,也因为为将来的扩展做准备,一个嵌入式数据库,如sqlite或firebird。第二个是一个令人难以置信的强大数据库,如果你想获得一个服务器,一个功能强大的服务器