winforms 如何验证自动完成组合框,使用户不会在vb.net中的自动完成列表之外键入内容

jhiyze9q  于 2023-10-23  发布在  .NET
关注(0)|答案(1)|浏览(117)

如何验证自动完成组合框,使用户不会在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

答案的结果

v6ylcynt

v6ylcynt1#

你现在的情况还需要再做些工作。首先,您的代码甚至无法编译,因为您有一个名为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"

请注意,AutoCompleteSourceListItems,而不是CustomSource。正如我在你的另一个问题中所说的,你可以使用列表项作为自动完成源。请注意,ValueMemberDisplayMember不同。这种绑定的关键在于,用户看到一个友好的名称并从该列表中进行选择,然后从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事件中,我们检查显示的文本是否与选定项的文本匹配。如果不匹配,则意味着输入的文本与列表项不匹配,因此我们不会让用户移动焦点,直到他们更改它。

相关问题