您应该将数据存储在变量中,而不是使用 UI 控件来存储数据。我不确定你是否真的需要在 ListBox 中显示数据,所以在下面的示例代码中我没有。
如果您使用 List(Of String) 而不是字符串数组,则在保存之前添加另一个项目会更简单。
我在示例中使用的Contains 方法可以采用第二个参数来比较项目 - 我猜你可能想忽略这种情况(例如“ABC”与“aBc”相同)所以我用StringComparer.CurrentCultureIgnoreCase。
我怀疑您想使用 Control.Validating Event 而不是 TextChanged 事件。验证数据后,使用Control.Validated 事件处理程序将其保存。
我在表单上放了一个 TextBox 和一个 Button,这样焦点就可以从 TextBox 上移开,例如当按下 tab 时,触发验证事件。
Imports System.IO
Public Class Form1
Dim dataFile As String = "C:\temp\grains.txt"
Dim alreadyUsed As List(Of String) = Nothing
Sub LoadAlreadyUsed(filename As String)
'TODO: Add exception checking, e.g., the file might not exist.
alreadyUsed = File.ReadAllLines(filename).ToList()
End Sub
Sub SaveAlreadyUsed(filename As String)
File.WriteAllLines(dataFile, alreadyUsed)
End Sub
Function CodeIsAlreadyUsed(newCode As String) As Boolean
Return alreadyUsed.Contains(newCode, StringComparer.CurrentCultureIgnoreCase)
End Function
Private Sub TextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
' Do nothing if the user has clicked the form close button
' See https://stackoverflow.com/questions/15920770/closing-the-c-sharp-windows-form-by-avoiding-textbox-validation
If Me.ActiveControl.Equals(sender) Then
Exit Sub
End If
Dim txt = DirectCast(sender, TextBox).Text
If CodeIsAlreadyUsed(txt) Then
MessageBox.Show("This code has already been used.", "Cheat attempt violation", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
e.Cancel = True
End If
End Sub
Private Sub TextBox1_Validated(sender As Object, e As EventArgs) Handles TextBox1.Validated
' The Validated event is raised before the FormClosing event.
' We do not want to save the data when the form is closing.
If Me.ActiveControl.Equals(sender) Then
Exit Sub
End If
Dim txt = DirectCast(sender, TextBox).Text
alreadyUsed.Add(txt)
SaveAlreadyUsed(dataFile)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadAlreadyUsed(dataFile)
End Sub
End Class