用于“记住”消息的方法。过去的条目 [英] Method to "remember" past entries
问题描述
我在VB中构建的应用程序的一部分具有终端功能,我想向其中添加功能,以便它可以按时间顺序记住过去的命令,类似于windosw终端的工作原理。
Part of an application I'm building in VB has terminal functionality, and I'd like to add functionality to it so it remembers past commands in chronological order, similarly to how a windosw terminal works.
简而言之,我希望您能够在文本区域成为焦点时按向上箭头,并能够循环显示先前输入的命令列表。
In short I'd like you to be able to press the up arrow when the text area is focused and be able to cycle through a list of commands that were entered previously.
我对此有两个想法:
-
一个组合框,当您按Enter键,将读取combobox.text中的内容,无论是新输入的命令还是旧的已选择的命令。然后将该命令添加到组合框的项目中,以便您可以向上滚动并再次找到它。
A combobox that, when you hit enter, reads whatever is in combobox.text, whether that be a newly entered command or an old one that was selected. Then add that command to the items of the combobox so you could scroll up and find it again.
一个简单的文本框,当按下向上箭头时,循环浏览一些存储的队列并相应地设置文本。
Simply a textbox that, when the up arrow is pressed, cycles through some stored queue and sets the text accordingly. This would requires a second queue to remember the cycled through commands and replace them, correct?
这是否需要任何第二个队列来记住循环遍历的命令,对不对?在Visual Basic的结构中,这样做会更好,还是有更好的方法呢?
Are there any built-in structures of Visual Basic that would be better for this, or is there some better way of doing it?
感谢您的帮助。
推荐答案
听起来您正在寻找最近使用过的列表。
It sounds like you are looking for something like a Most Recently Used List.
您想出<$ c通常,$ c> ComboBox 是正确的选择。用 TextBox
做您建议的操作,在很大程度上会导致... ComboBox
。
You idea for the ComboBox
is probably generally the right thing to do. To do what you suggest with a TextBox
would largely result in...a ComboBox
.
注意事项:
- 是否区分大小写?
FooBar
匹配fooBar
吗? - 不是堆栈(或队列)正确的工具,因为如果他们使用列表中索引4中的内容,则没有简单的方法将该项目从#4移至#1。
- 要在
ComboBox
作为UI选择器,您想使用一些可用作绑定源的东西。
- Is it is case sensitive? Does
FooBar
matchfooBar
? - A Stack (or Queue) is not the right tool for this because if they use something from index 4 in the list, there is no easy way to move that item from #4 to #1.
- To use this with a
ComboBox
as the UI picker, you want to use something that will work as a binding source.
这是一个新生的MRU类:
Here is a nascent MRU class:
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)
构建的,因此您可以将其绑定到Listbox
或ComboBox
。 - When they pick an existing item, it moves from whence it was to the top of the list.
- It is case insensitive, "Able" matches "ABLE". But it is case-aware: if/when they type an item again, it uses the new casing. So if "ZIggy" is in the list at slot 3, if they type in "Ziggy" correctly, they old one is removed and the new one used.
- There is a capacity limiter so you wont get absurdly long lists. When the lists gets too long, old items are dropped.
- It is built from a
BindingList(Of String)
so that you can bind it to aListbox
orComboBox
.
列表管理在后台非常浪费。每次我们在 myList(0)
处插入一个新项目时,.NET都必须移动和跳动基础数组。理想的收集类型应该是 LinkedList
,但这不能用作绑定源,我不怀疑您将存储数千个项目。
The List management is pretty wasteful under the hood. Each time we insert a new item at myList(0)
.NET has to shift and jigger the underlying array around. The ideal collection type would be a LinkedList
, but that wont work as a binding source and I dont suspect you will have 1000s of items being stored.
Private myMRU As New MRUList(8)
...
' bind to CBO in form_load:
cboMRU.DataSource = myMRU.DataList
将事物添加到列表后,它们将自动出现在列表。当用户进行选择时
As things are added to the list they will automatically appear in the list. When the user makes a selection
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
我使用了离开
事件,因为他们可以从列表中选择或。您的代码不需要执行任何操作就可以检查新项目还是现有项目,添加
方法可以为您完成此操作。
I used the Leave
event because they can pick from the list or select an item from the list. You code doesn't need to do anything as far as checking for new vs existing items, the Add
method does that for you.
在左侧,我输入了4项,最后一个是 Delta
。接下来,我正确输入了可以
。该类删除了旧的,并将新的作为新拼写的MRU浮动到顶部。
On the left, I entered 4 items, Delta
being the last one. Next, I typed in Able
correctly. The class removed the old one and floated the new one to the top as the MRU with the new spelling.
由于这些对您的代码有影响,请使用 thisCmd
,无论它们是什么。对于更复杂的事物,也许在其中键入的内容只是其他事物的键或令牌的情况下,请在 MRU <中使用
BindingList(TokenItem)
/ code>班级
Since these mean something to your code, use thisCmd
in the event for whatever they are. For more complex things, perhaps where what they type is just a key or token for something else, use a BindingList(of TokenItem)
in the MRU
Class
这篇关于用于“记住”消息的方法。过去的条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!