【问题标题】:ASP.NET AutoCompleteExtender-enabled TextBox's TextChanged-event doesn't fire when selecting certain kind of item from AutoCompleteExtender (whew...)从 AutoCompleteExtender 中选择某种项目时,启用 ASP.NET AutoCompleteExtender 的 TextBox 的 TextChanged 事件不会触发(哇...)
【发布时间】:2025-11-29 13:20:19
【问题描述】:

今天我遇到了一个非常奇怪的问题,由存储过程、自动完成扩展器和事件处理组成。如果有人可以为以下传奇建议一个简洁的标题,请做!

首先我会尝试介绍玩家(有些部分有点删节),然后是场景。环境是VS2008、C#、SQL Server 2005和ASP.NET。

数据库表:

TABLE (
 SomeNbr  INT,
 SomeAbbr VARCHAR(10),
 Name     VARCHAR(30)
)

存储过程:

读取上表并返回如下内容:

DECLARE @Results TABLE
(
    SomeNbr INT,
    --Composite CHAR(50), -- voodoo magic starts here...
    Composite VARCHAR(50)
) 

返回表的复合字段由 SomeNbr、SomeAbbr 和 Name 字段组成。它们被附加在一起并用逗号分隔(例如“数字、缩写、名称”)。

存储过程用于从 db 中检索一组行,并将这些行放入一个类型化的数据表中。然后将该数据表存储在会话变量中。 DataTable 的 XSD 架构具有“复合”字段的数据类型字符串。

!重要!对于数据库中的某些行,“名称”字段包含实际值和最大长度的填充(由空格组成)。其他只包含没有 rpadding 的名称。

用户界面(带有代码隐藏的 ASPX 页面):

我已经扩展了文本框控件以包含来自 AJAX 控件工具包的 AutoCompleteExtender。控制声明如下:

<ajx:TextControl ID="txtControl" 
                 runat="server" 
                 AutoPostBack="true" 
                 UseAutoComplete="true" 
                 ServiceMethod="GetItems" 
                 MinimumPrefixLength="1" />

用户界面上有一些额外的基本文本框。

代码隐藏:

AutoCompleteExtender 使用以下网络方法:

[System.Web.Services.WebMethod]
public static string[] GetItems(string prefixText, int count)
{
    try
    {
        return Utility.GetMatchingStrings(_DataTableInSession, prefixText);
    }        
    catch (Exception ex)
    {
        throw;
    }
}

GetMatchingStrings(...) - 方法将 preFixText 与 _DataTableInSession 中的所有数据行进行比较,并返回匹配字符串的数组。使用数据行的“复合”字段进行比较。

在代码隐藏中,事件处理程序被设置:

extendedTextControl.Control.TextChanged += PopulateTextControls;    

,并且:

private void PopulateTextControls(object sender, EventArgs e)
{
    // Read Text-property from extended textcontrol
    string str = extendedTextControl.Text;

    // Split string by commas and take parts into an array
    string[] arrStr = SplitString(",", str);

    // Set the values in array to Text-properties of TextBoxes
    SetValuesToTextBoxes(arrStr, _TextBoxes);
}

场景

一切似乎都很好,扩展的 TextControl 正在按预期工作,并在文本框下方生成可选列表。

场景 1:

现在,当用户从自动完成列表中选择一个项目时,会发生以下事情:

  1. 选定的字符串设置为扩展文本控件的文本属性
  2. textcontrol 的自动回发发生
  3. 在回发时,为 textcontrol 的 TextChanged 事件注册了一个事件处理程序
  4. TextChanged 事件被触发,其他文本框按预期填充数据

要发生这种情况,类型化数据行中的“复合”字段必须是这样的:

"10", "10, ABBR, Some Name Goes Here____..._" (

如果数据行更像这样:

"10", "10, ABBR, Some Name Goes Here"

那我们就去……

场景 2:

以上是一种快乐的一天-场景:-)

如果匹配的数据行是由 db 中的一行组成的,则不会触发 TextChanged 事件。

我花了好几个小时试图弄清楚上面的一切。首先,我很困惑为什么选择自动完成列表中的某些项目的****确实有效,而有些则无效。

当我意识到查看数据表的内容时,我发现有些行有填充,而另一些则没有。之后,我尝试 ltrim(rtrim()) SP 的返回表中的所有内容,但所有项目都不再起作用了。

之后我尝试将 SP 的返回值设置为 CHAR(50) 而不是 VARCHAR(50),并且修复了它。

问题:

我的应用程序发生了什么?为什么注册的事件不触发?就像 TextChanged 仅适用于特定长度的字符串(VARCHAR(50) 的最大长度),但这怎么可能呢?

问题已解决,但我不知道为什么。只是在办公室的另一天,我想:-)

我很乐意提供更多数据和说明!

编辑 1:添加了有关数据行中空格和下划线的注释。

【问题讨论】:

    标签: asp.net stored-procedures autocomplete event-handling ajaxcontroltoolkit


    【解决方案1】:

    之后我尝试将 SP 的返回值设置为 CHAR(50) 而不是 VARCHAR(50),并且修复了它。

    我不了解整个场景,但我会看看 CHAR(50) 与 VARCHAR(50) 的问题。我也不知道“WebOlkiUtility.GetMatchingStrings”是做什么的。

    declare @text char(50)
    select @text = 'test'
    
    select @text
    
    declare @text2 varchar(50)
    select @text2 = 'test2'
    
    select @text2
    
    -- output --
    CHAR(50): 'test                                              '
    VARCHAR(59): 'test2'
    

    CHAR(50) 总是返回 50 个字符!

    顺便说一句:你为​​什么要这样附加事件?

    if (GetPostBackingControlId() == extendedTextControl.ID)
    {
        extendedTextControl.Control.TextChanged += PopulateTextControls;
    }
    

    您可以随时附加它。在您的 ASPX 文件或 Page_Init 方法中。

    【讨论】:

    • 实用方法用于从数据表中获取匹配项。根据 AutoCompleteExtender 的要求,方法将匹配用户输入的项目作为字符串数组返回。事件处理程序代码看起来有点奇怪,但那是因为我删减了代码。我会稍微修改一下这个例子。
    最近更新 更多