無論是 Web 還是 WinForm 程式,為了方便使用者操作各類資料、提升操作體驗,始終是介面設計的核心議題。本文拋磚引玉,分享筆者在 Web 與 WinForm 中結合拼音簡碼與智能提示的具體實作案例,探討如何有效改善使用者搜尋體驗。
在 Web 介面中,使用者可輸入拼音首字母或部分中文內容進行模糊搜尋(類似 Google 搜尋的智能提示),一方面方便使用者快速定位資料,另一方面善用 Ajax 技術提升互動流暢度。
圖1:輸入拼音首字母觸發智能提示
圖2:輸入中文同樣支援智能提示
WinForm 介面同樣可實現智能提示,得益於本地響應速度較快,可根據輸入的首字母或部分中文即時更新列表內容:
圖3:WinForm 即時智能提示效果
上述兩種場景的核心需求一致:需要一個 SQL 函數將中文轉換為拼音首字母,以支援快速搜尋。以下提供 SQL Server 與 Oracle 兩種資料庫的實作:
-- Definition for user-defined function f_GetPy :
GO
CREATE FUNCTION [dbo].f_GetPy(@str NVARCHAR(4000))
RETURNS NVARCHAR(4000)
AS
BEGIN
DECLARE @strlen INT, @re NVARCHAR(4000)
DECLARE @t TABLE(chr NCHAR(1) COLLATE Chinese_PRC_CI_AS, letter NCHAR(1))
INSERT INTO @t(chr, letter)
SELECT '吖', 'A' UNION ALL SELECT '八', 'B' UNION ALL
SELECT '嚓', 'C' UNION ALL SELECT '咑', 'D' UNION ALL
SELECT '妸', 'E' UNION ALL SELECT '發', 'F' UNION ALL
SELECT '旮', 'G' UNION ALL SELECT '铪', 'H' UNION ALL
SELECT '丌', 'J' UNION ALL SELECT '咔', 'K' UNION ALL
SELECT '垃', 'L' UNION ALL SELECT '嘸', 'M' UNION ALL
SELECT '拏', 'N' UNION ALL SELECT '噢', 'O' UNION ALL
SELECT '妑', 'P' UNION ALL SELECT '七', 'Q' UNION ALL
SELECT '呥', 'R' UNION ALL SELECT '仨', 'S' UNION ALL
SELECT '他', 'T' UNION ALL SELECT '屲', 'W' UNION ALL
SELECT '夕', 'X' UNION ALL SELECT '丫', 'Y' UNION ALL
SELECT '帀', 'Z'
SELECT @strlen = LEN(@str), @re = ''
WHILE @strlen > 0
BEGIN
SELECT TOP 1 @re = letter + @re, @strlen = @strlen - 1
FROM @t a WHERE chr <= SUBSTRING(@str, @strlen, 1)
ORDER BY chr DESC
IF @@ROWCOUNT = 0
SELECT @re = SUBSTRING(@str, @strlen, 1) + @re, @strlen = @strlen - 1
END
RETURN(@re)
END
CREATE OR REPLACE FUNCTION F_PINYIN(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS
V_COMPARE VARCHAR2(100);
V_RETURN VARCHAR2(4000);
FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 AS
BEGIN
RETURN NLSSORT(P_WORD, 'NLS_SORT=SCHINESE_PINYIN_M');
END;
BEGIN
FOR I IN 1..NVL(LENGTH(P_NAME), 0) LOOP
V_COMPARE := F_NLSSORT(SUBSTR(P_NAME, I, 1));
IF V_COMPARE >= F_NLSSORT('吖') AND V_COMPARE <= F_NLSSORT('驁') THEN
V_RETURN := V_RETURN || 'A';
ELSIF V_COMPARE >= F_NLSSORT('八') AND V_COMPARE <= F_NLSSORT('簿') THEN
V_RETURN := V_RETURN || 'B';
ELSIF V_COMPARE >= F_NLSSORT('嚓') AND V_COMPARE <= F_NLSSORT('錯') THEN
V_RETURN := V_RETURN || 'C';
ELSIF V_COMPARE >= F_NLSSORT('咑') AND V_COMPARE <= F_NLSSORT('鵽') THEN
V_RETURN := V_RETURN || 'D';
ELSIF V_COMPARE >= F_NLSSORT('妸') AND V_COMPARE <= F_NLSSORT('樲') THEN
V_RETURN := V_RETURN || 'E';
ELSIF V_COMPARE >= F_NLSSORT('發') AND V_COMPARE <= F_NLSSORT('猤') THEN
V_RETURN := V_RETURN || 'F';
ELSIF V_COMPARE >= F_NLSSORT('旮') AND V_COMPARE <= F_NLSSORT('腂') THEN
V_RETURN := V_RETURN || 'G';
ELSIF V_COMPARE >= F_NLSSORT('妎') AND V_COMPARE <= F_NLSSORT('夻') THEN
V_RETURN := V_RETURN || 'H';
ELSIF V_COMPARE >= F_NLSSORT('丌') AND V_COMPARE <= F_NLSSORT('攈') THEN
V_RETURN := V_RETURN || 'J';
ELSIF V_COMPARE >= F_NLSSORT('咔') AND V_COMPARE <= F_NLSSORT('穒') THEN
V_RETURN := V_RETURN || 'K';
ELSIF V_COMPARE >= F_NLSSORT('垃') AND V_COMPARE <= F_NLSSORT('擽') THEN
V_RETURN := V_RETURN || 'L';
ELSIF V_COMPARE >= F_NLSSORT('嘸') AND V_COMPARE <= F_NLSSORT('椧') THEN
V_RETURN := V_RETURN || 'M';
ELSIF V_COMPARE >= F_NLSSORT('拏') AND V_COMPARE <= F_NLSSORT('瘧') THEN
V_RETURN := V_RETURN || 'N';
ELSIF V_COMPARE >= F_NLSSORT('筽') AND V_COMPARE <= F_NLSSORT('漚') THEN
V_RETURN := V_RETURN || 'O';
ELSIF V_COMPARE >= F_NLSSORT('妑') AND V_COMPARE <= F_NLSSORT('曝') THEN
V_RETURN := V_RETURN || 'P';
ELSIF V_COMPARE >= F_NLSSORT('七') AND V_COMPARE <= F_NLSSORT('裠') THEN
V_RETURN := V_RETURN || 'Q';
ELSIF V_COMPARE >= F_NLSSORT('亽') AND V_COMPARE <= F_NLSSORT('鶸') THEN
V_RETURN := V_RETURN || 'R';
ELSIF V_COMPARE >= F_NLSSORT('仨') AND V_COMPARE <= F_NLSSORT('蜶') THEN
V_RETURN := V_RETURN || 'S';
ELSIF V_COMPARE >= F_NLSSORT('侤') AND V_COMPARE <= F_NLSSORT('籜') THEN
V_RETURN := V_RETURN || 'T';
ELSIF V_COMPARE >= F_NLSSORT('屲') AND V_COMPARE <= F_NLSSORT('鶩') THEN
V_RETURN := V_RETURN || 'W';
ELSIF V_COMPARE >= F_NLSSORT('夕') AND V_COMPARE <= F_NLSSORT('鑂') THEN
V_RETURN := V_RETURN || 'X';
ELSIF V_COMPARE >= F_NLSSORT('丫') AND V_COMPARE <= F_NLSSORT('韻') THEN
V_RETURN := V_RETURN || 'Y';
ELSIF V_COMPARE >= F_NLSSORT('帀') AND V_COMPARE <= F_NLSSORT('咗') THEN
V_RETURN := V_RETURN || 'Z';
END IF;
END LOOP;
RETURN V_RETURN;
END;
///
/// 根據商品名稱獲取商品列表
///
public List<GoodsInfo> FindByName(string goodsName)
{
string sql = string.Format("Name LIKE '%{0}%' OR dbo.f_GetPy(Name) LIKE '{0}%'", goodsName);
return this.Find(sql);
}
資料存取層:
///
/// 獲取公司名稱(支援中文與拼音首字母搜尋)
///
public List<string> GetTopCompanyName(int topCount, string name)
{
string sql = string.Format(@"
SELECT * FROM (
SELECT Company_Name FROM tb_enterprise
WHERE Company_Name LIKE '%{1}%' OR F_PINYIN(Company_Name) LIKE '%{1}%'
) WHERE ROWNUM <= {0} ORDER BY ROWNUM ASC", topCount, name);
DataTable dt = SqlTable(sql);
List<string> list = new List<string>();
foreach (DataRow row in dt.Rows)
list.Add(row[0].ToString());
return list;
}
前台頁面:
<td align="left" style="background-color: #F1F6FF; width: 200px;">
<asp:TextBox ID="txtCompanyName" runat="server" Width="200"></asp:TextBox>
<cc1:AutoCompleteExtraExtender ID="AutoCompleteExtraExtender1" runat="server"
ServiceMethod="GetCompanyNameList"
TargetControlID="txtCompanyName" AsyncPostback="false" UseContextKey="True" AutoPostback="true"
MinimumPrefixLength="2" CompletionInterval="10" OnItemSelected="AutoCompleteExtraExtender1_ItemSelected">
</cc1:AutoCompleteExtraExtender>
</td>
後台程式碼:
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string[][] GetCompanyNameList(string prefixText, int count, string contextKey)
{
List<string[]> list = new List<string[]>();
List<string> nameList = BLLFactory<Enterprise>.Instance.GetTopCompanyName(count, prefixText.ToUpper());
for (int i = 0; i < nameList.Count; i++)
{
string[] Respuesta = new string[2];
Respuesta[0] = nameList[i];
Respuesta[1] = i.ToString();
list.Add(Respuesta);
}
return list.ToArray();
}
protected void AutoCompleteExtraExtender1_ItemSelected(object sender, EventArgs e)
{
// 根據使用者選擇的項目更新顯示相關內容
BindData();
}
如此即可在介面輸入簡單的英文字元或中文名稱,自動彈出智能提示列表,選擇後顯示相關資訊。
Web 開發中為實現 Ajax 智能提示效果,需引用特殊類庫:AutoCompleteExtra.rar