2012年11月27日 星期二

你的產品可能輸在「說話」的語氣


字級:

很多產品都會對我們說話。
我指的不光是像Siri這類真的會發出聲音的產品,其他像是網站、微軟Windows、手機裡的app等等,也都會透過文字和圖片訊息跟我們對話。它們透過這些訊息告訴我們該怎麼做(說明訊息)、不可以怎麼做(錯誤訊息)、目前的狀況或是處理進度等等。
這些訊息,並非我們想像的那麼「中性」,它們其實常在不知不覺間夾帶了「語氣」與「態度」,並因而影響了使用的感受與體驗。
譬如過去Windows惡名昭彰的藍白畫面,表面上是非常「中立」的系統技術訊息,但看在不熟悉電腦的人眼裡,那一大堆看不懂的代碼像是0157:BF7FF831,加上fatal之類的單字,很難不感到些許威嚇或害怕的感覺。
Windows 95/98當機畫面 來源:維基百科網頁截圖
當然,也有一些設計師試圖用更為人性化,甚至是幽默俏皮的方式來和使用者對話。譬如新的Windows 8就修改了藍白畫面的設計,是不是感覺稍微好一些了呢?
Windows 8 當機畫面 來源:維基百科網頁截圖
又譬如知名網站推特(twitter)非常有名的當機畫面:小鳥鯨魚圖與小貓修理圖。
Twitter 小鳥救鯨魚修復畫面 Photo Credit : Todd Barnard @ Flickr CC BY SA 2.0
Twitter Error 500 WAIT i'll fix it 小貓修理畫面 Photo Credit : psd @ Flickr CC BY 2.0
所以,不論你是設計師、工程師還是專案經理都好。不妨想想,你負責的產品是否會對使用者說話呢?
如果會的話,它是怎麼說話的?它的語氣,它的遣詞用字,它給人的感受到底是怎麼樣的呢?如果把它想像成一個人,在使用者的心目中,它是個什麼樣的人呢?
更重要的是,這些訊息的設計並不只是留下一些俏皮的小故事,讓人聊天或寫文章的時候可以拿來說嘴而已。而是會確實的影響使用體驗,甚至改變使用者對於你產品客觀效能的判斷。
史丹佛大學的B.J. Fogg教授,在他2002年出版的著作《Persuasive Technology》中,提到了一個有趣的小故事。
在90年代中期時,他曾經幫一家生產示波器的廠商研究其使用者,想了解這些專業工程師在使用該公司示波器的感受。
在示波器的螢幕底部,有一個非常小的區塊用來顯示各種文字訊息。而不幸的,該廠商設計的說明訊息口氣有點嚴苛而且不友善,在錯誤訊息上尤其如此。
「不就是一行訊息嗎?有那麼重要嗎?搞不好根本沒人在看呢。」如果你是這樣想的話,恭喜你,因為該公司負責寫這些訊息的開發人員可能也是這麼想的。
但Fogg教授發現,就是這個小小的區塊,改變了使用者對產品的感受與評價。當時該廠商的市場不斷被競爭對手奪走,而競爭對手產品的說明訊息,正好有著更為友善且溫暖的語氣
於是Fogg設計了一套新的說明訊息,並把新舊兩個版本的示波器拿去做對照實驗。結果發現,幾乎在每一項衡量指標上,受測者都給了友善的新版本較高的分數。有趣的是,也許是新的訊息產生了光環效應,受測者甚至認為新版示波器顯示的訊息更加精準。(別忘了,新舊版本只有訊息的語氣有改變,機器本身的準確度是一模一樣的)
所以,別再認為訊息就只是一行文字而已了。人們的使用經驗很可能在不知不覺間就被這些文字所影響,甚至改變了使用者對於產品本身客觀效能的判斷。
除了不友善的「口氣」與「個性」可能造成不良的使用體驗,另一個容易發生的問題則是「人格分裂」。舉例來說,一個網站也許前後有不同的開發人員經手,裡頭的文字訊息出自許多不同的成員手筆。這可能會造成網站的訊息個性不一,時而友善、時而嚴厲、時而沉穩、時而俏皮,於是使用者就只好被迫和一個人格分裂的網站打交道了。
最後,雖然在Fogg教授的故事裡,友善而溫暖的訊息獲得了勝利,但並不表示這是唯一的可能性。不妨先問自己,我做的是什麼產品?使用產品的是怎麼樣的人?在什麼樣的情境下使用?而我的產品應該扮演的角色是什麼?這個角色的個性與說話口氣又應該是什麼?
當然,也別忘了檢查一下產品裡的所有訊息,可別讓它「人格分裂」了。

2012年11月15日 星期四

修改Android系統gps.conf文件 讓GPS快速抓到衛星!


網路上教學要讓GPS快速抓衛星的文章有很多!
但教學文章眾說紛紜 到底要用哪個?
如果你是住在台灣、使用Android系統請跟著我試試看!


修改作業前提醒手機必須經過root取得系統最高權限才能進行修改
修改最佳APProot explorer

這裡主要是修改一個檔案
位置在/system/etc底下有一個名稱為"gps.conf
找到gps.conf它後對它長按住兩秒
然後會跳出選單
接下來請選擇"以本文編輯器方式打開"
而內容就直接修改成如下
如果你有使用Google瀏覽器的傳文字或連結套件
可以直接複製下面淺藍底色部分傳到手機再貼上去
這樣快很多、也不用怕輸入錯誤
NTP_SERVER=tw.pool.ntp.org
XTRA_SERVER_1=http://xtra1.gpsonextra.net/xtra.bin
XTRA_SERVER_2=http://xtra2.gpsonextra.net/xtra.bin
XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra.bin
SUPL_HOST=supl.nokia.com
SUPL_PORT=7276
另外關於上面提到SUPL_HOST和SUPL_PORT的選擇還有
SUPL_HOST=supl.google.com 
SUPL_PORT=7276

不過其實大同小異!

上面修改完成後記得保存
而點保存時它會自動備份一個原始檔
所以不用怕修改了如果還要改回來時不知道怎修改
修改完後記得重新開機
然後就可以到戶外測試囉!

再修改前原本以為大家講的10秒之內定位都是騙人的
等修改完才知道是真的!
就算在小巷子,對天空只有一條小線
也可以在30秒內定位完成!

以上都只單純開GPS,不開Wifi或其他網路去協助定位!

2012年11月5日 星期一

TabPanel 滑鼠移過 能自動開啟

 <asp:TabPanel ID="TabPanel1" runat="server">
                            <HeaderTemplate>
                                <div width="100%" onmouseover="activeTab(0)" onclick="stopClickEvent(event)">
                                    <img alt='' src="images/tf18.png"></div>
                            </HeaderTemplate>


 <asp:TabPanel ID="TabPanel2" runat="server">
                            <HeaderTemplate>
                                <div width="100%" onmouseover="activeTab(1)" onclick="stopClickEvent(event)">
                                    <img alt='' src="images/tf18.png"></div>
                            </HeaderTemplate>


---

<script type="text/javascript">
        function stopClickEvent(evt) {
            var e = (evt) ? evt : window.event;
            if (window.event) {
                e.cancelBubble = true; //ie
            } else {
                e.stopPropagation(); //Firefox
            }
        }

        function activeTab(index) {
            if (index !== $find("<%=TabContainer1.ClientID%>").get_activeTabIndex()) {
                if (index == 0)
                    $find("<%=TabContainer1.ClientID%>").set_activeTab($find("<%=TabContainer1.Tabs[0].ClientID%>"));
                else
                    $find("<%=TabContainer1.ClientID%>").set_activeTab($find("<%=TabContainer1.Tabs[1].ClientID%>"));
            }
        }
    </script>

2012年11月1日 星期四

CDATA 區段 - XML 標準

XML 對於許多人都不陌生,但還是有些地方大家不知道該如何使用,例如現在所要介紹的 CDATA 區段。

在某些時候內容中含有 HTML 標籤或者是一些特殊字元﹙如﹕<、>、&﹚,當這些字元出現在內容裡,通常都會出現 XML 分析錯誤的情況,這時候就必須將這些字元作些轉換的工作(如︰< / &lt;、> / &gt;、& / &amp;)。

其實並不需要如此,CDATA 區段提供了一種通知剖析器的方法,說明 CDATA 區段所包含的字元沒有標記。

當 XML 剖析器遇到開頭的『<![CDATA[』,會將接下來的內容報告成字元,而不會嘗試將其解譯成項目或實體標籤。字元參考不能在 CDATA 區段內運作。當它遇到結尾的『]]>』時,剖析器會停止報告並回到正常的剖析,這也能使用在 HTML 文件中。使用方法為︰ 
  1. <![CDATA[這裡面內容包含了 <font size="3">HTML 標籤</font>,以前一些特殊字元 & 所以要使用 CDATA 區段包起來]]>  

以下面商品資料文件 PDI0120080331195202.xml 為範例,其中 PDI01DOC.DocContent.Item.ProductUrl 為商品頁面的網址,內容包含了 & 字元;PDI01DOC.DocContent.Item.ProductDesc 為商品說明,內容包含了大量 HTML 標籤。所以這兩個內容我們都用使用了 CDATA 區段包起來,如此 XML 剖析器就能正常剖析了。 

2012年10月31日 星期三

對初心者有助益的 MSDN 文件庫索引整理 (一)


轉:http://www.dotblogs.com.tw/billchung/archive/2012/02/15/69375.aspx

       MSDN 文件庫中其實有一部份是對於初心者建立正確的程式設計基礎很有幫助的內容,也許很多人一看到 MSDN 文件庫龐大的內容就不知所措,完全不知該從何看起,因此就整理一份索引筆記給大夥兒參考參考,或許不盡完善,不過我就是盡力列出來吧。

       Visual Studio 的使用
       位於 [Visual Studio 應用程式開發] 這節中,其中以下幾個小節關於方案、專案、編譯平台設定、建置偵錯與程式碼編輯器的使用是我認為應優先閱讀的:
       (1) [管理方案、專案和檔案]
         (1-1) [方案、專案和項目簡介]
         (1-2) [專案屬性 (Visual Studio)]
           (1-2-1) [使用專案設計工具管理專案屬性]
         (1-3) [多專案的方案]
         (1-4) [以特定的 .NET Framework 版本或設定檔為目標]

       (2) [編輯程式碼和資源檔]

       (3) [建置與偵錯]
         (3-1) [在 Visual Studio 中建置]
         (3-2) [Visual Studio 偵錯]

       (4) [部署應用程式和元件] :這可以等到你需要做程式部署時候再讀


       四個 Step By Step 範例
       在 [使用者入門教學課程] 中有四個 Step By Step 的範例,如果你對開發環境不太熟悉建議你從這四個範例一步步跟著做,不要急著做完每個步驟,在你練習的時候要靜下心來思考每個步驟的意義是什麼,而不是囫圇吞棗地趕進度做完練習。

       程式設計概念
       在 [程式設計概念] 一節中,我覺得最重要先閱讀及瞭解的是 [物件導向程式設計 (C# 與 Visual Basic)] 這部份,尤其是前半段關於類別與物件的部份,初心者應該要先有所瞭解,至於繼承、介面、泛型與委派可在對物件導向稍有熟悉後再回頭詳加閱讀。有些人寫了幾年的 .Net 程式整個架構還是拼拼湊湊有一部份的原因就是沒有在物件導向的基礎上下過功夫 (雖然他們誤以為他們也是在寫物件導向程式) ,只會上網路東抄西抄 (關於這點我還真佩服他們主管的忍受力) ,甚至連註解都一字不漏照抄。

       Visual Basic 使用者
       如果你使用的語言是Viusal Basic,[Visual Basic] 這個章節能有助於你對Visual Basic的瞭解,尤其以下小節:
       (1) [使用 Visual Basic 開發應用程式]
         (1-1) [使用 Visual Basic 開發環境]
           (1-1-1) [HOW TO:在 Visual Basic 中編譯並執行專案]

       (2) [Visual Basic 程式設計手冊]
         (2-1) [程式結構和程式碼慣例 (Visual Basic)]
           (2-1-1) [Visual Basic 程式的結構]
           (2-1-2) [Visual Basic 版的 Hello World]
           (2-1-3) [Visual Basic 中的 Main 程序]
           (2-1-4) [參考和 Imports 陳述式 (Visual Basic)]:配合 (2-1-5) 區分清楚組件與命名空間的差異。
           (2-1-5) [Visual Basic 中的命名空間]
           (2-1-6) [Visual Basic 命名慣例]
           (2-1-7) [Visual Basic 編碼慣例]:這篇非常的重要,務求徹底瞭解。
           (2-1-8) [程式碼中的特殊字元 (Visual Basic)]
           (2-1-9) [程式碼中的註解 (Visual Basic)]
           (2-1-10) [Visual Basic 中的 Me、My、MyBase 和 MyClass]

         (2-2) [Visual Basic 語言功能]
           (2-2-1) [Visual Basic 中的陣列]:此節中的相關主題務必加入你的閱讀清單,有助於釐清與解決大部份關於陣列使用上的問題。
           (2-2-2) [Visual Basic 中的集合]
           (2-2-3) [Visual Basic 的常數和列舉型別]
           (2-2-4) [Visual Basic 中的控制流程]:程式設計非常重要的基礎,當你還是初學者時如果在這上面下過苦工夫就不會像一些人寫了兩三年控制流程還寫的零零落落。
           (2-2-5) [Visual Basic 中的資料型別]:關於型別有一個很重要的概念在VS.90 版本的連結 [實值型別和參考型別]。不過在 VS.100 版本中已併到 [資料型別實作 (Visual Basic)] 中,不要看輕型別這檔事,以為自己用的理所當然,當你寫到一定程度的程式後,型別的問題可能就會是程式碼中隱形的盲點。初期可以先略過 [Visual Basic 中的泛型型別 (Visual Basic)],因為泛型在初期實在不是個很好懂的東西。
           (2-2-6) [Visual Basic 的宣告項目]:宣告項目中,Dim、Const、Enum、Class、Structure、Module、Function、Sub 、Property 列為優先瞭解對象。
           (2-2-7) [Visual Basic 中的物件和類別]:務必弄清楚類別、物件(或稱執行個體) 與物件變數間的不同;執行個體成員和共用成員的不同等等。
           (2-2-8) [Visual Basic 中的運算子和運算式]:和流程控制一樣這是非常重要的基礎。
           (2-2-9) [Visual Basic 中的程序]:程式結構化的基礎,以下為初心者必讀重點,其餘部份可在熟悉基礎後再詳加閱讀:
             (2-2-9-1) [HOW TO:建立程序 (Visual Basic)]
             (2-2-9-2) [Sub 程序 (Visual Basic)]
             (2-2-9-3) [Function 程序 (Visual Basic)]
             (2-2-9-4) [程序參數和引數 (Visual Basic)]
             (2-2-9-5) [程序多載化 (Visual Basic)]
           (2-2-10) [Visual Basic 中的字串]
           (2-2-11) [Visual Basic 中的變數]

       (3) [Visual Basic 參考]


C# 使用者
       (1) [使用 Visual C# 開發環境] 老實說我覺得這部份寫的沒有 Visual Basic 那部份來的好,相關章節的內容一大部份來自於第一篇介紹的 [Visual Studio 應用程式開發] 中。
         (1-1) [HOW TO:將應用程式組態檔加入至 C# 專案]:這算是其中比較有趣的章節,如果會用到.config 檔案存取應用程式組態可參考此節。


       (2) [C# 程式設計手冊]
         (2-1) [C# 程式內部]
           (2-1-1) [Hello World -- 您的第一個程式 (C# 程式設計手冊)]:大家都愛的 Hello World,如果完全沒寫過程式,這是一個好的起點。
           (2-1-2) [C# 程式的一般結構 (C# 程式設計手冊)] :這篇也比 Visual Baisc 類似的章節少了很多,我只感覺這篇主要在介紹麻花捲 { }。
           (2-1-3) [C# 編碼慣例 (C# 程式設計手冊)]:這個區塊中最重要的就是這節了,對於初心者來講,委派 LINQ可以暫時先跳過。


         (2-2) [陣列 (C# 程式設計手冊)]:此節中的相關主題務必加入你的閱讀清單,有助於釐清與解決大部份關於陣列使用上的問題。


         (2-3) [類別和結構 (C# 程式設計手冊)]:此節中初心者可略去泛型型別匿名型別擴充方法隱含型別區域變數。以下為必讀重點:
           (2-3-1) [類別 (C# 程式設計手冊)]
           (2-3-2) [物件 (C# 程式設計手冊)]:一樣提醒要分清楚類別、物件(或稱執行個體) 與物件變數間的不同。
           (2-3-3) [結構 (C# 程式設計手冊)
           (2-3-4) [成員 (C# 程式設計手冊)]:這一節其實很奇怪,它包含的就是以下這幾樣
           (2-3-5) [欄位 (C# 程式設計手冊)]
           (2-3-6) [常數 (C# 程式設計手冊)]
           (2-3-7) [屬性 (C# 程式設計手冊)]:尤其要注意 Property 與 Field 的差異。
           (2-3-8) [方法 (C# 程式設計手冊)]:初學者請先閱讀本節主要內容與以下一節即可
             (2-3-8-1) [傳遞參數 (C# 程式設計手冊)]
           (2-3-9) [建構函式 (C# 程式設計手冊)]:解構函式可以未來再懂,但建構函式一定要先弄懂。
           (2-3-10) [物件和集合初始設定式 (C# 程式設計手冊)]
             (2-3-10-1) [HOW TO:使用物件初始設定式初始化物件 (C# 程式設計手冊)]
             (2-3-10-2) [HOW TO:使用集合初始設定式來初始化字典 (C# 程式設計手冊)]
         

         (2-4) [集合類別 (C# 程式設計手冊)]:概觀看一下瞭解定義。
           (2-4-1) [HOW TO:使用 foreach 存取集合類別 (C# 程式設計手冊)]:初學者在此節主要是瞭解 foreach 陳述式。


         (2-5) [例外狀況和例外處理 (C# 程式設計手冊)]
            (2-5-1) [使用例外狀況 (C# 程式設計手冊)]
            (2-5-2) [例外處理 (C# 程式設計手冊)]
            (2-5-3) [HOW TO:使用 try/catch 處理例外狀況 (C# 程式設計手冊)]
            (2-5-4) [HOW TO:使用 finally 執行清除程式碼 (C# 程式設計手冊)]


         (2-6) [Main() 和命令列引數 (C# 程式設計手冊)]
         (2-7) [命名空間 (C# 程式設計手冊)]
         (2-8) [陳述式、運算式和運算子 (C# 程式設計手冊)]:以下三節為初心者必讀。
            (2-8-1) [陳述式 (C# 程式設計手冊)]
            (2-8-2) [運算式 (C# 程式設計手冊)]
            (2-8-3) [運算子 (C# 程式設計手冊)]


          (2-9) [字串 (C# 程式設計手冊)]
          (2-10) [型別 (C# 程式設計手冊)]

       (3) [C# 參考]
         (3-1) [C# 關鍵字]
         (3-2) [C# 運算子]


       如果你撰寫資料存取的程式
       假設要參考相關的資料庫存取程式,首推的章節必然是 [ADO.NET],對於初心者而言可略過 LINQEntity FrameworkWCF (我知道這幾個玩意很重要,不過對初學者來講太硬了),不妨從以下基礎章節看起。

       (1) [ADO.NET 概觀]
         (1-1) [ADO.NET 架構]:快速瞭解一下 ADO.NET 倒底是什麼玩意。
         (1-2) [.NET Framework Data Providers (ADO.NET)]:瞭解什麼是 Data Provider 與如何選用。
         (1-3) [ADO.NET DataSet]:瞭解DataSet 物件模型 (雖然到了後來你可能會越來越少用 DataSet)。
         (1-4) [ADO.NET 中的並存執行]
         (1-5) [ADO.NET 程式碼範例]
         (1-6) [保護 ADO.NET 應用程式]:雖然安全性的議題對於初心者來講會比較難理解,但為了一開始能建立正確的觀念,強烈建議起碼要瀏覽過此節內容。尤其在使用SQL敘述時不正確的方式易造成SQL Injection。這裡的每一部份都很重要,務請反覆地在學習各階段中都回頭複習,直到你能夠習慣寫出安全的程式碼為止。
         (1-7) [ADO.NET 中的資料型別對應]:我是覺得這比較偏查詢用,就是有時候搞不太清楚各類資料型別對應時可以查。
         (1-8) [DataSet、DataTable 及 DataView (ADO.NET)]:這節也相當重要,因為它有很多實做的練習,不熟的話請務必花點時間細讀。


         (1-9) [擷取和修改 ADO.NET 中的資料]:這邊幾乎就是一步步重頭教你怎麼使用 ADO.NET 的語法,對於初心者來講尤以底下幾節特別要先看。
           (1-9-1) [連接至資料來源 (ADO.NET)]
             (1-9-1-1) [建立連接 (ADO.NET)]
           (1-9-2) [連接字串 (ADO.NET)]
           (1-9-3) [命令和參數 (ADO.NET)]:這節我覺得 CommandBuilders 的部份就不用看了,因為那玩意不太實用。
             (1-9-3-1) [執行命令 (ADO.NET)]:瞭解各種命令的使用時間,才不會亂 Execute 一通。
             (1-9-3-2) [設定參數和參數資料型別 (ADO.NET)]:再次強調這個非常非常重要,拜託不要再寫出一堆用字串硬串的條件式歡迎別人攻擊你的資料庫,請從一開始養成用 DbParameter 的習慣。
             (1-9-3-3) [從資料庫取得單一值 (ADO.NET)]:這是個 ExecuteScalar 的範例。
             (1-9-3-4) [使用命令來修改資料 (ADO.NET)]]:這是個 ExecuteNonQuery 的範例。

2012年10月29日 星期一

使用 AutoCompleteExtender 為網頁添加「自動完成」效果


OK! 你已經知道怎麼安裝 AJAX Control Toolkit 而且已經安裝好了,然後你想利用 AutoCompleteExtender 來為某些 TextBox 控制項添加自動完成的功能(很簡單),而此功能所提示的項目清單要來自另一個 WCF Service,而不是來自網頁本身提供的 Web Method 或某個 Web Service(其實也很簡單)。最後,還想套用自訂的 CSS 來改善自動完成清單的顯示樣式。

開發工具

  • Visual Studio 2010
  • AJAX Control Toolkit .NET 4

快速入門
  1. 把一個 ToolkitScriptManager 和一個 TextBox 控制項拖到你的 ASP.NET 網頁上。
  2. 為 TextBox 加上 AutoCompleteExtender:從 TextBox 控制項的智慧標籤選單中點 Add Extender,然後選擇 AutotCompleteExtender。參考下圖:

  3. 同樣利用 TextBox 控制項的智慧標籤選單,點選其中的 Add Autocomplete page method,如下圖所示。


  4. 這樣會為你目前的網頁添加一個 GetCompletionList 方法。你只要把取得自動完成清單的邏輯寫在這裡就行了。參考底下的程式碼:
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string[] GetCompletionList(string prefixText, int count, string contextKey)
{
    return new string[] { "台北市", "新北市", "台中市"};
}

此方法套用了兩個特徵項:WebMethodAttribute 和 ScriptMethodAttribute,表示此方法可以被當作 Web Service 呼叫,也可以在用戶端網頁中透過 jQuery 或其他 AJAX 技術呼叫。這裡的 ScriptMethodAttribute 可以省略,但 WebMethodAttribute 不可省略,否則用戶端會呼叫不到此方法。

方法的參數 prefixText 就是使用者在網頁上輸入的字串;你可以根據此資訊來決定要傳回的清單項目,例如,prefixText 若為 "台",就傳回以「台」開頭的縣市名稱,如台北市、台中市、台南市等等。這裡我只是簡單的傳回三個固定的縣市名稱。

參數 count 就是對應到用戶端網頁中的 AutoCompletExtender 控制項的 CompletionSetCount 屬性,代表用戶端想要從伺服器端取得幾筆建議項目。參數 contextKey 則是對應到 ContextKey 屬性,這是給你自己額外運用的自訂參數。

要注意的是,此方法的名稱可以讓你任意修改,但方法的參數名稱絕對不可改,連大小寫都要完全一樣,否則用戶端網頁會呼叫不到。 

你可以開啟網頁的 .aspx 原始碼,看看 AutoCompletExtender 控制項還有哪些屬性。比較重要的是 ServicePath 和 ServiceMethod 屬性。由於此範例是把取得建議清單的 method 直接產生在目前網頁的類別裡,所以你應該只會看到 ServiceMethod 屬性有設定值,而沒有 ServicePath。當你修改了伺服器端的 GetCompletionList 方法的名稱,記得要一併修改用戶端網頁中的 ServiceMethod 屬性,這兩個名稱若不相符,自動完成的效果肯定出不來。

接著在瀏覽器中檢視此網頁,試一下效果。當你在 TextBox 中輸入超過三個字元時,TextBox 下方就會出現自動完成的建議清單。輸入幾個字元就要觸發自動完成,是由 AutoCompletExtender 的 MinimumPrefixLength 屬性來控制。

後端改用 WCF Service

如果你想要寫一個 WCF Service,提供自動完成的建議清單給其他 ASP.NET 網頁,就不要像前面示範的步驟 3 那樣自動產生網頁方法,而是由我們手動建立這個方法。

做法很簡單,首先在網站中加入一個 AJAX-enabled WCF Service,將它命名為 AddressService.svc。

然後開啟 AddressService.cs,為 AddressService 類別加入我們的 GetCompleteList 方法:

[OperationContract]
public string[] GetCompletionList(string prefixText, int count, string contextKey)
{
    string[] cities = new string[] { "台北市", "新北市", "台中市", "高雄市", "台南市", "桃園縣" };

    return cities.Where<string>(s => s.StartsWith(prefixText)).Take<string>(count).ToArray<string>();
}

這裡我稍微加了一點比對字串的邏輯:字串陣列 cities 用來模擬我們從資料庫取回的查詢結果,然後再從這個陣列中選取前 n 筆(由 Take 方法負責)符合前導字串 prefixText 的縣市名稱。

接著修改 ASP.NET 網頁上的 AutoCompleteExtender 控制項的屬性:
  • ServicePath="AddressService.svc"
  • ServiceMethod="GetCompletionList"
  • MinimumPrefixLength="1" (因為縣市名稱只有三個字,我們希望使用者只輸入一個字就能立刻出現建議清單。)

ASP.NET 網頁原始碼:

    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <ajaxToolkit:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server"
        ServicePath="AddressService.svc" ServiceMethod="GetCompletionList" TargetControlID="TextBox1"
        UseContextKey="True" MinimumPrefixLength="1">
    </ajaxToolkit:AutoCompleteExtender>

執行結果如下圖:




套用 CSS 來改變外觀

前面的範例執行結果,那個自動完成清單顯示的位置離 TextBox 太遠了,而且我想要修改顯示的字型和顏色,怎麼辦呢?還好 AutoCompleteExtender 還提供了一些屬性可讓我們套用自訂的 CSS 來改變其預設外觀。主要是這幾個屬性:

  • CompletionListCssClass
  • CompletionListItemCssClass
  • CompletionListHighlightedItemCssClass

簡單起見,我就把 CSS 直接內嵌在網頁裡。修改後的 ASPX 原始碼如下(部分標籤省略):

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        .completionListElement
        {
            visibility: hidden;
            margin: 0px !important;
            background-color: inherit;
            color: black;
            border: solid 1px gray;
            cursor: pointer;
            text-align: left;
            list-style-type: none;
            font-family: Verdana;
            font-size: 12px;
            padding: 0;
        }
        .listItem
        {
            background-color: white;
            padding: 1px;
        }
        .highlightedListItem
        {
            background-color: #c3ebf9;
            padding: 1px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
    </ajaxToolkit:ToolkitScriptManager>
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <ajaxToolkit:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server"
            ServicePath="AddressService.svc" ServiceMethod="GetCompletionList" TargetControlID="TextBox1"
            CompletionListCssClass="completionListElement" CompletionListItemCssClass="listItem"
            CompletionListHighlightedItemCssClass="highlightedListItem" UseContextKey="True"
            MinimumPrefixLength="1">
        </ajaxToolkit:AutoCompleteExtender>
    </div>
    </form>
</body>
</html>

套用 CSS 之後的執行結果如下圖: