使用AutoCompleteExtender實作文本框自動比對
引言
Ajax Control Toolkit 是一個豐富的控件集,可以為我們提供許多很炫也很實用的頁面功能。編寫一個Asp.Net Ajax控件是比較耗費精力的,不僅需要有一定的javascript腳本編寫能力,還需要了解微軟的Ajax Library。如果我們急需一些效果,那麼可以直接使用Ajax Control Toolkit 所提供的一些功能。但是如果想要完全明白它是如何運作的,還是需要認真地學習一下如何編寫一個Asp.Net Ajax控件。我個人覺得Asp.Net Ajax控件能夠較好地将以前的編寫的javascript特效也融合到了.Net控件中,這樣既利于javascipt代碼的重用,更便于日後的使用,而不是一定要在控件中使用Ajax方式與服務端進行一次通信往來。
在Ajax Control Toolkit中包含了兩類控件,其中一類字尾為Extender,也就是“擴充”的意思,這類控件可以對現有Asp.Net的能力進行擴充,來實作一些更華麗的效果。這篇文章簡單介紹一下Ajax Control Toolkit中的AutoCompleteExtender如何使用,顧名思義,它可以實作一個常見的效果:AutoComplete(自動比對)。
編寫WCF Service代碼
在進行AutoComplete時,是将用戶端文本框中輸入的值與伺服器端的資料相比較,這樣就需要在服務端建立一個方法,它能夠接受來自用戶端文本框輸入的字元串,并且針對此字元串對資料庫或者其他資料源中的資料進行查找,然後将比對的結果以字元串數組的形式傳回給用戶端,最後用戶端将獲得的結果以清單形式顯示在輸入文本框的下面。盡管前面的描述隻有短短的幾句話,但是卻暗含了這樣幾個問題需要注意:
- 由于每次用戶端輸入時都要進行一個查找和比對的過程,是以要查找的資料源如果不大的話,應該盡量緩存在服務端記憶體中,而不是每次查找比對都去通路實際的存儲位置,比如說資料庫。
- 有可能使用者輸入的字元串會傳回極大量的結果,比如30個,為了提升服務端查找的效率,也為了不在用戶端顯示極長的清單,可以限制傳回的結果數目。
- AutoComplete是為了根據使用者輸入的字元判斷使用者的 意圖 ,然後傳回可能的結果。如果使用者隻輸入一個字元,比如a,就開始進行查找比對,對于使用者來說意義不大,而且也會加重服務端負擔,因為此時往往會傳回極長的清單。
了解了上面3個問題,我們現在在站點下建立一個Ajax-Enabled WCF Service,起名為AutoCompleteService,然後在App_Code中修改AutoCompleteService.cs:
// 上面的特性省略
public class AutoCompleteService
{
private static string[] cityArray; // 将資料值緩存在靜态字段中
public string[] getListFromDatabase() {
if (cityArray != null && cityArray.Length > 0)
return cityArray;
// 這裡通常是由資料庫擷取
cityArray = new string[]{
"Baotou",
"Beihai",
"Beijing",
"Boao",
// ...省略若幹
};
return cityArray;
}
[OperationContract]
public string[] GetCityList(string prefixText, int count) {
string[] cityArray = getListFromDatabase();
List<string> findCity = new List<string>(count);
int i = 0; int j = 0;
while (i < cityArray.Length && j < count) {
string pre = cityArray[i].Substring(0, prefixText.Length).ToLower();
if (pre.Equals(prefixText.ToLower())) {
findCity.Add(cityArray[i]);
j++;
}
i++;
}
return findCity.ToArray();
}
這裡我們使用一個靜态字段緩存了資料源中的結果,以符合上面所說的第1條。接下來我們看一下GetCityList()方法,它接受兩個參數:prefixText,代表用戶端文本框中已經輸入的值;而count表示傳回的結果數目。第2個參數展現了我們前面所說的第2點。方法的實作沒有什麼好說的,無非是周遊集合,傳回與prefixText相比對的結果。這裡要特别說明的是:因為這個方法要與aspx頁面上的AutoCompleteExtender控件協作,是以方法的簽名必須為:public string[] XXXXX(string prefixText, int count),其中XXXX代表任意合法的方法名稱,但是參數的類型和名稱則必須完全一緻。
Web頁面實作
Web頁面的實作就更為簡單了,因為我們使用Ajax Control Toolkit中的現成控件,是以不需要自己編碼,隻需要對控件的屬性進行設定一下就可以了。因為我們要使用Web服務,是以需要首先在ScriptManager中對服務進行一下注冊:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/AutoCompleteService.svc" />
</Services>
</asp:ScriptManager>
接着我們在頁面拖放一個Asp.Net Textbox控件,以及一個AutoCompleteExtender控件,并向下面這樣對AutoCompleteExtender控件設定屬性:
輸入城市(拼音)
<span id="autoBox">
<asp:TextBox ID="TextBox1" runat="server" Width="160"></asp:TextBox>
</span>
<br /><br />
<ajaxControlToolkit:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server"
ServicePath="AutoCompleteService.svc"
ServiceMethod="GetCityList"
MinimumPrefixLength="2"
CompletionSetCount="10"
EnableCaching="true"
TargetControlID="TextBox1"
>
</ajaxControlToolkit:AutoCompleteExtender>
TextBox和通常的沒有任何差別,是以我們隻要看下AutoCompleteExtender就可以了。我們設定了這樣幾個屬性:
- TargetControlID:因為它是一個Extender擴充控件,相當于是擴充了現有控件的功能,是以這個TargetControlID說明了它要對哪個控件進行擴充,此處為TextBox1。
- ServicePath:指明了要使用的服務,注意這裡隻需寫名稱,而無需指定全路徑。
- ServiceMethod:服務的方法名稱,即是上面所指定的GetCityList。
- MinimumPrefixLength:當文本框中輸入的字元串小于這個長度時,不進行比對,可以看到,這個可以滿足我們一開始所說到的第3條。
- CompletionSetCount:傳回的最大的比對數,也就是GetCityList的count參數的值。
- EnableCaching:啟用緩存,将之前比對的結果緩存起來。
接下來運作頁面,應該可以看到這樣的結果:

總結
在這篇文章中,實作了當今Web頁面中很常見的一個AutoComplete功能,我們首先分析了實作的過程中可能會存在的問題,随後借助Ajax Control Toolkit中的AutoCompleteExtender控件輕松地進行了實作。
感謝閱讀,希望這篇文章能給你帶來幫助!