如何验证自动完成组合框,以便用户不会在 vb.net 中的自动完成列表之外键入内容。因此,我希望用户必须从自动完成组合框中选择列表,而不是手动键入,并且在按键盘退格键时,用户无法按 esc 键盘键,因为这也可以在列表之外创建。有可能实现吗?.
也许我编写的代码仍然是错误的,请指导我
谢谢
Private Class Item
Public Property Codeproduct() As String
Public Property Barcode() As String
End Class
Private source As BindingSource = Nothing
Private items As List(Of Items) = Nothing
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
items = New List(Of Items)()
items.AddRange({
New Items() With {
.CODEPRODUCT = "TEST",
.BARCODE = "1000"
},
New Items() With {
.CODEPRODUCT = "Andrea",
.BARCODE = "2000"
},
New Items() With {
.CODEPRODUCT = "Arnold",
.BARCODE = "3000"
},
New Items() With {
.CODEPRODUCT = "Barbara",
.BARCODE = "4000"
},
New Items() With {
.CODEPRODUCT = "Billy",
.BARCODE = "5000"
},
New Items() With {
.CODEPRODUCT = "Clint",
.BARCODE = "6000"
},
New Items() With {
.CODEPRODUCT = "Cindy",
.BARCODE = "7000"
}
})
source = New BindingSource()
source.DataSource = items
ComboBox1.AutoCompleteMode = AutoCompleteMode.Suggest
ComboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
ComboBox1.AutoCompleteCustomSource.AddRange(items.Select(Function(n) n.CODEPRODUCT).ToArray())
Dim ComboBox1Bind As New Binding("Text", source, "CODEPRODUCT", True, DataSourceUpdateMode.OnPropertyChanged)
AddHandler ComboBox1Bind.Parse, Sub(s, evt)
source.CurrencyManager.Position = items.FindIndex(1, Function(r) r.CODEPRODUCT.Equals(evt.Value))
End Sub
ComboBox1.DataBindings.Add(ComboBox1Bind)
ComboBox1.DataSource = source
ComboBox1.ValueMember = "CODEPRODUCT"
ComboBox1.DisplayMember = "CODEPRODUCT"
End Sub
答案的结果
你所拥有的仍然可以做一些工作。首先,您的代码甚至无法编译,因为您有一个名为
Item
的类,但随后您创建了新的 Items
对象;一种甚至不存在的类型。此外,这些行毫无意义,而且可能有害:
Dim ComboBox1Bind As New Binding("Text", source, "CODEPRODUCT", True, DataSourceUpdateMode.OnPropertyChanged)
AddHandler ComboBox1Bind.Parse, Sub(s, evt)
source.CurrencyManager.Position = items.FindIndex(1, Function(r) r.CODEPRODUCT.Equals(evt.Value))
End Sub
ComboBox1.DataBindings.Add(ComboBox1Bind)
您应该在设计器中进行尽可能多的配置,然后仅使用代码来完成您必须做的事情。对于此示例,我在设计器中添加了
BindingSource
,并在那里完全配置了 ComboBox
。我需要在代码中使用 ComboBox
做的唯一事情就是设置 DataSource
。这是相关的设计师代码:
Me.ComboBox1.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest
Me.ComboBox1.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems
Me.ComboBox1.DisplayMember = "CodeProduct"
Me.ComboBox1.ValueMember = "Barcode"
请注意,
AutoCompleteSource
是 ListItems
,而不是 CustomSource
。正如我在其他问题中所说,您可以使用列表项作为自动完成源。请注意,ValueMember
与 DisplayMember
不同。这种绑定的要点在于,用户会看到一个友好的名称并从该列表中进行选择,然后您可以从 SelectedValue
中获取标识符。
用户代码如下所示:
Private Class Item
Public Property CodeProduct As String
Public Property Barcode As String
End Class
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim items As New List(Of Item) From {New Item() With {
.CodeProduct = "TEST",
.Barcode = "1000"
},
New Item() With {
.CodeProduct = "Andrea",
.Barcode = "2000"
},
New Item() With {
.CodeProduct = "Arnold",
.Barcode = "3000"
},
New Item() With {
.CodeProduct = "Barbara",
.Barcode = "4000"
},
New Item() With {
.CodeProduct = "Billy",
.Barcode = "5000"
},
New Item() With {
.CodeProduct = "Clint",
.Barcode = "6000"
},
New Item() With {
.CodeProduct = "Cindy",
.Barcode = "7000"
}}
BindingSource1.DataSource = items
ComboBox1.DataSource = BindingSource1
End Sub
Private Sub ComboBox1_Validating(sender As Object, e As CancelEventArgs) Handles ComboBox1.Validating
If ComboBox1.Text <> String.Empty AndAlso
Not String.Equals(ComboBox1.Text,
ComboBox1.GetItemText(ComboBox1.SelectedItem),
StringComparison.CurrentCultureIgnoreCase) Then
'The displayed text does not match the text of the selected item so it is invalid.
e.Cancel = True
End If
End Sub
项目列表已创建并绑定到控件。在
Validating
事件中,我们检查显示的文本是否与所选项目的文本匹配。如果不是,则意味着输入的文本与列表项不匹配,因此我们不会让用户转移焦点,直到他们更改它。