1

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

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

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

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

4

2 回答 2

1

您可以在用户输入文本的地方使用文本字段,并据此缩小下拉框中的选择范围。为了解决同名但不同公司的问题,您可以在括号中的名称后面列出公司的地址。如果用户输入的名称无效,请在文本字段旁边放置一个错误/警告图标。

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

于 2012-04-13T15:46:40.743 回答
1

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

本质上,您使用 AJAX AutoCompleteExtender (ACE) 修改标准文本框。这个 ace 引用了一个 Web 服务(我将对此进行说明),该服务会即时获取客户输入的信息。一旦启动并运行,它就非常酷。

这是一个例子:

.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 语句或其他内容)。

现在对于网络服务...(.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

很酷的是,您可以通过“您的硬编码列表”故意添加值,该列表将与您通过 Web 服务提取的任何值相结合。这样,如果您无法向数据库添加值,您可以直接添加值。

于 2012-04-13T17:21:25.627 回答