需要有关VB.NET ComboBox的AutoSuggest的建议

时间:2012-04-13 15:39:30

标签: vb.net combobox autosuggest

为了提供一些上下文,我有一个组合框,用户可以与之交互以选择一家保险公司。不幸的是,它们不仅仅需要名称;有时保险公司有相同的名称,区分它们的唯一方法是使用他们的地址(例如北卡罗来纳州的Medicare办公室与南卡罗来纳州的Medicare办公室)。我目前所做的是使用组合框的DrawItem事件在显示下拉列表时在ComboBox旁边绘制工具提示。列表本身显示保险公司名称,但工具提示将显示当前所选公司的地址。组合框设置为DropDownList,因此除了列表中的内容之外,它们不可能选择任何内容。

好吧,现在我被告知要改变它。用户不再满足于必须单击组合框或按箭头键。他们想要他们可以键入的组合框,并在键入时显示自动提示列表。这一切都很好,但这是我跑到墙上的地方。我可爱的使用工具提示的小方案在这种情况下无法工作,因为autosuggest列表是一个完全独立的控件。 DrawItem没有触及它,我找不到自定义绘制autosuggest列表的方法。另一个问题是autosuggest没有重复的条目,所以即使我有两个不同的保险公司,只有一个会出现在列表中,因为它们共享相同的名称。

到目前为止,我唯一的另一个想法就是在用户按下某个键时以某种方式将下拉列表滚动到相应的项目。但我无法弄清楚如何在未设置selectedindex的情况下在下拉列表中设置突出显示的项目。如果我使用selectedindex,它会继续并替换文本。

有没有人对如何进行有任何建议?我是在正确的轨道上,还是我努力工作并且需要完全做其他事情?

2 个答案:

答案 0 :(得分:1)

您可以使用用户在其文本中键入的文本字段,并根据该字段缩小投递箱中的选择范围。要绕过同名但不同的公司问题,您可以在括号中列出公司名称后面的公司地址。如果用户输入的名称无效,请在文本字段旁边添加错误/警告图标。

要在运行时更新选择,您可以向文本字段添加事件侦听器并查询当前文本以确定它是否是有效前缀。

答案 1 :(得分:1)

我们在我所在的公司做类似的事情。为了实现它,我们通过AJAX使用Web服务。

基本上,您使用AJAX AutoCompleteExtender(ACE)修改标准文本框。这个ace引用了一个webservice(我将说明),它可以获取客户即时输入的信息。一旦它启动并运行它就非常酷。

以下是一个例子:

的.ascx

<asp:TextBox ID="txtInsuranceCompany" runat="server" TabIndex="520" 
      AutoComplete="Off"AutoCompleteType="Disabled" CssClass="asbSearch" Width="350px"></asp:TextBox>
<ajax:AutoCompleteExtender ID="aceInsuranceCompany" runat="server" CompletionSetCount="20"
       MinimumPrefixLength="0" OnClientShown="resetPosition" ServiceMethod="LookupData"
       ServicePath="~/WebLookUpService.asmx" TargetControlID="txtInsuranceCompany" UseContextKey="true">
</ajax:AutoCompleteExtender>

一些微妙之处在于您必须确保为自动填充扩展器设置上下文密钥,并在Web服务中创建一些功能来加载您的值(我将再次说明)。

.vb代码隐藏

 Dim yourhardcodedlist As New List(Of String)
 yourhardcodedlist.Add("Progressive")
 yourhardcodedlist.Add("State Farm")
 yourhardcodedlist.Add("USAA")
 WebLookUpService.AddLookupValues(txtInsuranceCompany.ID, yourhardcodedlist.ToArray)
 aceInsuranceCompany.ContextKey = public_var0 & ":" & public_var1 & ":" & txtInsuranceCompany.ID

请注意,“public_var0”“和public_var1”不是必需的。这只是说明如何将更多信息传递给Web服务而不实际将其作为参数传递(即冒号分隔列表,您是Web服务函数可以解析出来以便在SQL语句中使用)。 / p>

现在为webservice ...(。asmx)

<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<System.Web.Script.Services.ScriptService()> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class WebLookUpService
    Inherits System.Web.Services.WebService

    <System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()> _
    Public Function LookupData(ByVal prefixText As String, ByVal count As Integer,  ByVal contextKey As String) As String()
    'Construct SQL statement to pull from database
    'parsing the context key as necessary to construct your SQL statement (if necessary)
    'Dim somethingForSql As String = contextKey.Split(":")
    Dim suggestions As List(Of String) = New List(Of String)

    Try

        Using cnADO As SqlConnection = New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("PublicSafetyServer").ToString)
            cnADO.Open()

            Dim dt As DataTable = New DataTable
            Dim da As New SqlDataAdapter
            da.SelectCommand = New SqlCommand("<YourSQLStatement>")         

            da.Fill(dt)

            Dim endRow As Integer = dt.Rows.Count
            If endRow > count Then
                endRow = count
            End If

            For i As Integer = 0 To endRow - 1
                Dim des As String = dt.Rows(i).Item(field)
                Dim val As String = dt.Rows(i).Item(field)
                suggestions.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(des, val))
            Next
        End Using

    Catch ex As Exception
        'Throw Error
    End Try

    suggestions.Sort()
    If suggestions.Count = 0 Then
        suggestions.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(noneFound, ""))
    End If
    Return suggestions.ToArray()
End Function

有什么好处,你可以通过'yourhardcodedlist'故意添加值,它将与你通过网络服务提取的任何值相结合。这样,如果无法向数据库添加值,则可以直接添加值。