提问人:siwa86 提问时间:10/4/2023 最后编辑:siwa86 更新时间:10/6/2023 访问量:121
当用户在 vb.net 中按多个键时,如何在文本框中处理
how to handle in textbox when the user presses multiple keys in vb.net
问:
当用户在 vb.net 中按多个键时,如何在文本框中处理。
当用户按键盘键 backspace 和 esc 而不回车时,存在用户可以在列表之外选择的问题。请指导我。 这是修改建议和准则后的以下代码 @dr.null
谢谢
Imports System.Data.OleDb
Public Class Form7
Private connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\dapperdemo.accdb;Persist Security Info=False;"
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = &H10 Then
Dim av = Me.AutoValidate
Me.AutoValidate = AutoValidate.Disable
MyBase.WndProc(m)
Me.AutoValidate = av
Return
End If
MyBase.WndProc(m)
End Sub
Private Sub Form7_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim acsCustomers As New AutoCompleteStringCollection
Using dt As DataTable = GetData()
acsCustomers.AddRange(
dt.AsEnumerable().
Select(Function(r) r.Field(Of String)("CODEPRODUCT")).ToArray())
End Using
TextBox1.AutoCompleteMode = AutoCompleteMode.Suggest
TextBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
TextBox1.AutoCompleteCustomSource = acsCustomers
'AutoValidate = AutoValidate.EnableAllowFocusChange
End Sub
Private Function GetData() As DataTable
Dim conString As String = connectionString
Dim query As String = "SELECT CODEPRODUCT FROM Items"
Dim dt As New DataTable()
Using con As OleDbConnection = New OleDbConnection(conString),
cmd As OleDbCommand = New OleDbCommand(query, con),
sda As OleDbDataAdapter = New OleDbDataAdapter(cmd)
sda.Fill(dt)
End Using
dt.AcceptChanges()
Return dt
End Function
Private Sub TextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
Dim product = TextBox1.Text.Trim()
Dim products = TextBox1.AutoCompleteCustomSource.Cast(Of String)
'If product.Length > 0 AndAlso products.Any() AndAlso
If products.Any() AndAlso
Not products.Contains(product, StringComparer.OrdinalIgnoreCase) Then
MessageBox.Show("Please Select From List Only...")
e.Cancel = True
TextBox1.SelectAll()
' Or
' TextBox1.Clear()
End If
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Enter Then
Me.ValidateChildren()
End If
End Sub
End Class
答:
此答案将涉及 .尝试一下,看看感觉是否正常。您将看到,当 设置为 时,它甚至不允许用户选择不在列表中的项目。这似乎是您正在寻找的行为,因为太宽容了。ComboBox
DropDownStyle
ComboBoxStyle.DropDownList
TextBox
我将把你的数据库查询移出UI。查询可能很快,但在这两种情况下,我都不会在 UI 上使用数据库查询提供答案。如果查询速度较慢,您会注意到 UI 性能有所提高。
Private Function GetCodeProducts() As IEnumerable(Of String)
Dim result As String()
Using dt As New DataTable(),
con As New OleDbConnection(connectionString),
cmd As New OleDbCommand("SELECT CODEPRODUCT FROM Items", con),
sda As New OleDbDataAdapter(cmd)
sda.Fill(dt)
dt.AcceptChanges() ' is this really necessary?
result = dt.AsEnumerable().Select(Function(r) r.Field(Of String)("CODEPRODUCT")).ToArray()
End Using
Return result
End Function
Private Function GetCodeProductsAsync() As Task(Of IEnumerable(Of String))
Return Task.Run(AddressOf GetCodeProducts)
End Function
没有理由返回 .你只需要一个字符串的枚举,所以它就在那里。如果您不关心定义两者,则非异步函数可以作为 lambda 包含在异步函数中。DataTable
Private Async Sub Form7_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim codeProducts = Await GetCodeProductsAsync()
ComboBox1.Items.AddRange(codeProducts.ToArray())
ComboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend
ComboBox1.AutoCompleteSource = AutoCompleteSource.ListItems
ComboBox1.DropDownStyle = ComboBoxStyle.DropDown
End Sub
请注意,Form_Load(一种 UI 方法)现在被标记为 ,并且我们是从数据库返回数据的任务的结果。Async
Await
在控件上填充并设置一些与“自动完成”相关的属性。另请注意,控件不需要进行任何验证或进行其他验证。此代码的行为将与当前版本完全相同,带有 TextBox
,并且没有我刚才提到的其他代码。ComboBox.Items
WndProc
如果将 更改为 ,则不允许用户选择列表中的项以外的任何内容。验证是内置的。你可能不喜欢这种感觉。DropDownStyle
DropDownList
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
使用样式,可以执行验证以强制用户在列表中输入内容。这具有您想要的自动完成功能。但是,它非常严格,并且不允许用户离开,直到他在列表中选择某些内容DropDown
ComboBox
Private Sub ComboBox1_Validating(sender As Object, e As CancelEventArgs) Handles ComboBox1.Validating
If Not ComboBox1.Items.Contains(ComboBox1.Text.Trim()) Then
MessageBox.Show("Please Select From List Only...")
e.Cancel = True
End If
End Sub
评论
RejectChanges
GetChanges
Select
DataView.RowStateFilter
DataView.RowFilter
AcceptChanges
Fill
Update
AcceptChangesDuringFill
AcceptChangesDuringUpdate
True
False
False
评论
If Not Me.ValidateChildren() Then Return
...basically simpler it would be to use a Pull-Down