创建基于AJAX技术的Scribble应用程序
生活随笔
收集整理的這篇文章主要介紹了
创建基于AJAX技术的Scribble应用程序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
簡介
ASP.NET Atlas是一套豐富的類庫,用于ASP.NET開發AJAX風格的應用程序。本文試圖解說Atlas框架的一般性特征,由于Atlas是一個龐大的庫,故本文集中探討Atlas的兩個最重要的特征:
1. 能夠從客戶端腳本中調用服務器端web服務
2. 使得開發跨瀏覽器兼容的JavaScript代碼相當容易
通過對這兩個特征的介紹,讀者朋友可以熟悉Atlas類庫的使用方法。
背景
MFC Scribble應用程序是學習MFC編程的著名例子之一。Scribble應用程序允許用戶使用鼠標自由涂畫。我在網絡中曾看見這樣一個類似的利用 AJAX技術的應用程序。但遺憾的是,這個JavaScript繪圖站點僅能在Firefox瀏覽器上運行。因此,我在本文中將解釋怎樣構建一個跨瀏覽器 版本的Scribble程序。
安裝Atlas
在本文完成時,可以點按這個鏈接下載Atlas的十 二月CTP。如果這個鏈接不能工作,你總可以轉到Atlas站點得到正確的鏈接。該Atlas庫可以作為Visual Studio 2005的一個模板(VSI)。在剛才的這個下載站點上有關于怎樣安裝這個模板的說明。
創建一個Atlas工程
一旦安裝了Atlas模板,你就可以通過點按菜單選項"File->New->Web Site"來創建一個空白的Atlas工程。然后就可以打開圖1所示的"New Web Site"對話框。
在"location"下面,可以選擇"File System"或"HTTP"。選擇HTTP將允許你基于一個IIS服務器的站點,而選擇File System將允許你在本地文件系統(你可以使用開發web服務器來進行調試和測試)上創建一站點。你可以選擇任何一個選項,但是我發現該應用程序如果使 用Internet Explorer且基于IIS運行效果更好一些。
Atlas空工程
上面最新創建的Atlas網站具有下列目錄結構:
· App_Data
這是放置數據文件的空目錄。
· Bin
這個目錄下放置相應于裝配集Microsoft.Web.Atlas的dll文件。這個目錄下包含了Atlas庫的服務器位置。
· ScriptLibrary
在這個目錄下,你可以放置該應用程序的任何JavaScript文件。
o Atlas
Atlas客戶端腳本放在這里,它有如下兩個子目錄:
§ Debug
Atlas客戶端JavaScript文件的調試版本放在這個目錄下。
§ Release
Atlas客戶端JavaScript文件發行版本放在這個目錄下。這個目錄下的腳本更為緊湊,并且去除了一些調試代碼。
Atlas客戶端腳本
Atlas的12月份發行版本提供了下面幾個客戶端腳本:
· Atlas.js
這是核心Atlas腳本文件,它包括了基本的工具函數和客戶端控件和組件。
· AtlasCompat.js
這個文件包含Atlas兼容層以支持Mozilla Firefox和Apple的iMac-Safari web瀏覽器。這個腳本可以確保Atlas代碼是跨瀏覽器兼容的。
· AtlasCompat2.js
這個文件包含其它函數以確保與Safari web瀏覽器的兼容性。
· AtlasRuntime.js
這是一個核心Atlas腳本文件的縮微版本,其中并不含有客戶端組件和控件。這個腳本文件在前面提到的組件或控件沒有使用時使用。
· AtlasUIDragDrop.js
包含工具函數,用于提供網頁中的鼠標拖放功能。
· AtlasUIGlitz.js
包含工具函數,用于提供網頁中的動畫和其它特殊效果。
· AtlasUIMap.js
支持使用Virtual Earth的Atlas映射框架的腳本文件。
其它文件
Atlas還把下面文件添加到網站的根目錄下。
· Default.aspx和Default.aspx.cs
該網頁包含Atlas腳本管理器控件-負責生成參考Atlas客戶端腳本的腳本塊。一個test/xml-script塊類型的客戶端腳本也被添加到該頁面上。這個腳本塊用于使用聲明性XML語法寫腳本。
· eula.rtf
· readme.txt
· Web.Config
這個web.config是運行Atlas應用程序所必需的。它包含一些Atlas特定的配置設置,并且可以在這個文件中添加Atlas HTTP模塊和HTTP處理器。
Scribble應用程序
該Scribble應用程序允許用戶拖動鼠標左鍵自由繪制圖案。當用戶釋放鼠標按鈕或移動到繪畫區域外面時,結束一個筆畫。可以使用JavaScript并利用VML技術來實現作畫,但是我們在本文中不準備使用VML。
在Scribble的默認網頁上將出現一幅圖像(常規的具有IMG標簽的HTML圖像)。用戶在該圖像上的鼠標事件能夠被JavaScript事件處理 器所捕獲。該JavaScript函數能夠把繪制筆畫相應的點系列發送到一個web服務中。該web服務通過把所有由用戶發送來的點繪制成線同時更新保存 在會話變量中的圖像對象。最后,客戶端向服務端請求一個更新后的圖像。該圖像源是一個HTTP處理器,它把存儲在會話變量中的圖像對象流向客戶端。下面是 該應用程序的主要組成部件。
· Default.aspx
擁有動態圖像和Atlas腳本管理器控件的頁面。
· ScribbleImage.ashx
這是一個HTTP處理器,它實現把存儲在會話變量中的圖像對象轉換為流式數據。
· ScribbleService.asmx
所有的繪畫請求發送到這個web服務中。這個web服務實現圖像修改。
· Scribble.js
該應用程序相應的主要JavaScript代碼駐留在這個文件中,以達到設計與代碼的清晰分離。
· Global.asax
Session_Start和Session_End事件是在Global.asax中處理的。Session_Start用于創建會話變量,而Session_End用于釋放存儲在會話變量中的圖像。
Global.asax
我們從Global.asax文件開始進行我們的編碼過程。
1. 在"Website"菜單上點擊"Add New Item"或按下Ctrl +Shift+A組合鍵。
2. 在"Add New Item"對話框中選擇"Global Application Class"并且點擊ok。你會看到Global.asax文件被自動創建。
3. 一開始,我們導入System.Drawing命名空間。這只要在上面文件的第一行的后面插入下面一行代碼即可:
<%@ Import Namespace="System.Drawing" %>
4. 添加下列代碼到Session_Start函數。
這部分代碼創建一個簡單的白色200×200像素的位圖,背景全為白色并把它賦給會話變量Image。
5. Session_End函數應該釋放掉存儲在會話變量中的圖像。
6. 從"Website"菜單中選擇"Add Reference"。
7. 在"Add Reference"對話框中選擇"System.Drawing"并且點擊OK。
8. 最后,在"Build"菜單下點擊"Build Web Site"或按組合鍵Ctrl+Shift+B來確保沒有構建錯誤。
這個web處理器用于把存儲在會話變量中的圖像數據流回客戶端。
1. 在"WebSite"菜單中點擊"Add New Item"或按下Ctrl+Shift+A。
2. 在"Add New Item"對話框中選擇"Generic Handler",然后把該處理器的名字設置為ScribbleImage.ashx并且點擊OK。
3. 一個web處理器要使用會話變量,它需要實現接口IRequiresSessionState。這是唯一的標記接口并且沒有要重載的方法。如下所示編輯該類的聲明:
4. 接下來,我們把代碼添加到Proce***equest方法。
o 第一行設置相應于image/png的響應的ContentType頭。這確保瀏覽器認出該響應是一個png圖像而不是普通HTML代碼。
o 緊接著的四行向瀏覽器指明不應該緩沖這個響應。所有的這四行都是必要的,用于確保該代碼是跨瀏覽器兼容的。我們將在本教程的以后的版本中優化這些代碼。
o 最后,會話變量中的位圖被存儲到一個內存流中,而該內存流的內容被寫到響應中。由于圖像是二進制數據,所以這里使用了BinaryWrite函數。
ScribbleService.asmx
我們有辦法來初始化會話圖像并把該圖像內容轉換成流作為響應。現在,我們需要一些方法來把內容添加到圖像本身。我們期望客戶調用ScribbleService.asmx web服務以把線段添加到圖像上。
1. 在"WebSite"菜單中點擊"Add New Item"或按下Ctrl+Shift+A。
2. 在"Add New Item"對話框中選擇"Web Service",指定名為ScribbleService.asmx并且點擊OK。確保未選定"Place Code in a Separate File"。
3. 通過把下列一行添加到命名空間語句中來導入命名空間System.Drawing:
using System.Drawing;
4. 接下來,我們需要為繪制點定義一個簡單的類。我們不能使用System.Drawing.Point類,因為它是不可以XML串行化的。在后面的內容中, 我們將會看到我們怎樣使用System.Drawing.Point來代替定制的類。現在我們先在ScribbleService類聲明之前添加下面代 碼:
5. 最后,我們需要添加一個方法來使用一組給定的點進行繪制。我們把一個web方法Draw添加到我們的web服務。
o 屬性WebMethod(EnableSession=true)保證會話變量可從web服務中進行存取。
o 圖像被鎖定以確保并發存取的安全性。
o 繪制本身很簡單,因為它僅是把在points數組中提供的點連接起來。
Scribble.js
我們讓服務器端圖像處理器和服務器端web服務來更新圖像。現在,我們需要創建在scribble應用程序中的客戶端腳本,由它來把來自鼠標動作的點發送到服務器web服務。
1. 點擊在解決方案資源管理器中的ScriptLibrary文件夾。
2. 在"WebSite"菜單中點擊"Add New Item"或按下Ctrl+Shift+A。
3. 在"Add New Item"對話框中選擇"JScript File",指定名字為Scribble.js并且按OK。這將把Scribble.js文件放到ScriptLibrary文件夾下。
4. 然后,我們需要聲明一些全局變量。在scribble的第一個版本中,我們將使用全局變量,但是在以后的版本中我們開始使用JavaScript對象。
在一個繪制請求被發送到服務器后,這里的iter變量用來修改圖像的源。在Internet Explorer情況下,設置image.src=image.src的確可以刷新該圖像,但是相同的代碼無法在Firefox中工作。為此,我們需要維 護變量iter,這個變量在每次Draw請求發送到Web服務時加1。我們把重復操作次數添加到originalSrc變量中,這樣瀏覽器認為它需要請求 服務器獲取刷新數據,而不是使用緩沖圖像的方式。
5. 定義函數startStroke,它響應mousedown事件開始一個筆畫。
當一個新筆畫開始時,我們創建一個新的點集合,見上面代碼的第一行。第二行取消該事件的默認行為。當相應于一個圖像的mousedown事件的默認行為將開始一次拖動操作時,這是必需的;這樣以來可以防止激活進一步的事件。
6. 當一個響應于一次mouseup事件或mouseout事件的筆畫結束時,我們需要實際調用web服務。這是在endStroke函數中完成的。
該函數中唯一讓人感興趣的一行是ScribbleService.Draw(points,onWebMethodComplete, onWebMethodTimeout,onWebMethodError);它異步地調用在ScribbleService.asmx中的web服務方 法Draw。Atlas框架使得這一函數可以自動為我們所用。
7. 當在web服務方法中發生錯誤時,將激活onWebMethodError,而當web方法調用超出定義在Atlas框架中可配置的時限時,onWebMethodTimeout函數被調用。在這個版本中,我們僅向用戶顯示一個帶有錯誤文本的消息框。
當web方法調用成功時,onWebMethodComplete函數被調用;這時需要重新加載圖像。
我們創建一個Image對象shimImage并且把它的源設置為我們正在繪制的圖像的最原始的源。當圖像對象加載時,我們把在該頁面中的實際HTML圖像元素的源設置為臨時圖像對象的源,這樣做可以避免在替換圖像時產生閃爍現象。
8. 我們需要在mousemove事件期間填充points數組。這是在addPoints函數中實現的。
o 新的點對象被使用事件對象的offsetX和offsetY屬性構建,并隨后被添加到points數組中。offsetX和offsetY屬性給出了相對的鼠標位置,這相當于產生該事件的HTML元素。
o 如果數組的長度達到3,那么我們能夠自動地請求服務器實現一個繪制操作并且重置points數組。這樣以來,用戶在他釋放掉鼠標按鈕前可以看到繪制過程。
9. 最后,我們需要鉤住事件,這是在pageLoad函數中完成的。
o pageLoad是一個特別函數,當Atlas框架完成加載后它被激活。我們使用this來取代常規的窗口或體(body)加載事件,這樣我們可以確保Atlas已經完成加載。
o 實際要畫的圖像元素被放置在一個具有id drawingSurface的div標簽中。該元素的大小與該圖像的大小相同,這樣我們可以安全地把事件依附到drawingSurface div上面。
Default.aspx
應用程序所需要的單獨組件必須被裝配到Default.aspx頁面中。下面是這個頁面的代碼。
這個頁面的最重要的部分是atlas:ScriptManager服務器控件。ScriptManager服務器控件負責為Atlas和任何web服務 代理腳本生成客戶端腳本塊。下面讓我們分析一下Default.aspx頁面中的ScriptManager控件的使用。
1. EnableScriptComponents屬性被設置為false。這生成了一個參考AtlasRuntime.js而不是參考Atlas.js的客 戶端腳本塊。因為我們沒有使用任何Atlas組件或控件,所以在這個版本的scribble教程中我們比較喜歡輕量級版本的Atlas框架。我們把一個服 務參考添加到ScribbleService.asmx web服務。這將為web服務代理生成一個到客戶端腳本的URL參考。
2. 我們也把Scribble.js文件作為另一個腳本參考添加到該服務上。
這把上面所討論的各項功能都聯合到一起,現在你可以編譯和運行該工程了。我鼓勵你看一下實際的由Atlas腳本管理器所生成的客戶端html。
Atlas魔術
下面是Atlas框架為我們所做的:
1. 它允許我們創建web應用程序而不需要為使其跨瀏覽器而付出特殊努力。web服務調用和客戶端事件處理可自動地工作于Internet Explorer和Firefox瀏覽器上。Atlas框架把所需要的JavaScript原型添加到Firefox對象以使其看起來象Internet Explorer對象。Internet Explorer的特定函數,如attachEvent,event.offsetX和event.offsetY都可以應用于Firefox。你可以通 過AtlasCompat.js文件來對此進行進一步分析。
2. 它自動地為Scribble web服務方法創建一個JavaScript代理。該JavaScript代理腳本文件相應于一個ScribbleService.asmx文件擁有 URL ScribbleService.asmx/js。這被添加在web.config文件中的Atlas HTTP模塊所產生。
小結
我們已經看到了如何調用web服務與如何容易地使用Atlas來編寫跨瀏覽器的應用程序。在以后的教程中,我們會看到更多的Atlas客戶端控件與聲明性編程(依賴于用戶反饋!)。
下載并使用源代碼
由于Atlas目前還不是可重發布的,所以我沒把Atlas文件包括到下載的源碼中。要使下載的源碼能夠工作,您需要按以下步驟操作。
1. 你需要從Atlas Web Site下載Atlas。
2. 在下載Atlas空白的工程模板以后,通過菜單命令File-New-Web Site創建一新的網站
3. 把源zip文件展開到新建的工程目錄下以覆蓋任何現有文件。
4. 在"Website"菜單下選擇"Add Existing Item",從網站的根目錄下添加上ScribbleService.asmx和ScribbleImage.ashx,并且從ScriptLibrary文件夾下添加上文件Scribble.js。
5. 構建并運行該網站。
ASP.NET Atlas是一套豐富的類庫,用于ASP.NET開發AJAX風格的應用程序。本文試圖解說Atlas框架的一般性特征,由于Atlas是一個龐大的庫,故本文集中探討Atlas的兩個最重要的特征:
1. 能夠從客戶端腳本中調用服務器端web服務
2. 使得開發跨瀏覽器兼容的JavaScript代碼相當容易
通過對這兩個特征的介紹,讀者朋友可以熟悉Atlas類庫的使用方法。
背景
MFC Scribble應用程序是學習MFC編程的著名例子之一。Scribble應用程序允許用戶使用鼠標自由涂畫。我在網絡中曾看見這樣一個類似的利用 AJAX技術的應用程序。但遺憾的是,這個JavaScript繪圖站點僅能在Firefox瀏覽器上運行。因此,我在本文中將解釋怎樣構建一個跨瀏覽器 版本的Scribble程序。
安裝Atlas
在本文完成時,可以點按這個鏈接下載Atlas的十 二月CTP。如果這個鏈接不能工作,你總可以轉到Atlas站點得到正確的鏈接。該Atlas庫可以作為Visual Studio 2005的一個模板(VSI)。在剛才的這個下載站點上有關于怎樣安裝這個模板的說明。
創建一個Atlas工程
一旦安裝了Atlas模板,你就可以通過點按菜單選項"File->New->Web Site"來創建一個空白的Atlas工程。然后就可以打開圖1所示的"New Web Site"對話框。
在"location"下面,可以選擇"File System"或"HTTP"。選擇HTTP將允許你基于一個IIS服務器的站點,而選擇File System將允許你在本地文件系統(你可以使用開發web服務器來進行調試和測試)上創建一站點。你可以選擇任何一個選項,但是我發現該應用程序如果使 用Internet Explorer且基于IIS運行效果更好一些。
Atlas空工程
上面最新創建的Atlas網站具有下列目錄結構:
· App_Data
這是放置數據文件的空目錄。
· Bin
這個目錄下放置相應于裝配集Microsoft.Web.Atlas的dll文件。這個目錄下包含了Atlas庫的服務器位置。
· ScriptLibrary
在這個目錄下,你可以放置該應用程序的任何JavaScript文件。
o Atlas
Atlas客戶端腳本放在這里,它有如下兩個子目錄:
§ Debug
Atlas客戶端JavaScript文件的調試版本放在這個目錄下。
§ Release
Atlas客戶端JavaScript文件發行版本放在這個目錄下。這個目錄下的腳本更為緊湊,并且去除了一些調試代碼。
Atlas客戶端腳本
Atlas的12月份發行版本提供了下面幾個客戶端腳本:
· Atlas.js
這是核心Atlas腳本文件,它包括了基本的工具函數和客戶端控件和組件。
· AtlasCompat.js
這個文件包含Atlas兼容層以支持Mozilla Firefox和Apple的iMac-Safari web瀏覽器。這個腳本可以確保Atlas代碼是跨瀏覽器兼容的。
· AtlasCompat2.js
這個文件包含其它函數以確保與Safari web瀏覽器的兼容性。
· AtlasRuntime.js
這是一個核心Atlas腳本文件的縮微版本,其中并不含有客戶端組件和控件。這個腳本文件在前面提到的組件或控件沒有使用時使用。
· AtlasUIDragDrop.js
包含工具函數,用于提供網頁中的鼠標拖放功能。
· AtlasUIGlitz.js
包含工具函數,用于提供網頁中的動畫和其它特殊效果。
· AtlasUIMap.js
支持使用Virtual Earth的Atlas映射框架的腳本文件。
其它文件
Atlas還把下面文件添加到網站的根目錄下。
· Default.aspx和Default.aspx.cs
該網頁包含Atlas腳本管理器控件-負責生成參考Atlas客戶端腳本的腳本塊。一個test/xml-script塊類型的客戶端腳本也被添加到該頁面上。這個腳本塊用于使用聲明性XML語法寫腳本。
· eula.rtf
· readme.txt
· Web.Config
這個web.config是運行Atlas應用程序所必需的。它包含一些Atlas特定的配置設置,并且可以在這個文件中添加Atlas HTTP模塊和HTTP處理器。
Scribble應用程序
該Scribble應用程序允許用戶拖動鼠標左鍵自由繪制圖案。當用戶釋放鼠標按鈕或移動到繪畫區域外面時,結束一個筆畫。可以使用JavaScript并利用VML技術來實現作畫,但是我們在本文中不準備使用VML。
在Scribble的默認網頁上將出現一幅圖像(常規的具有IMG標簽的HTML圖像)。用戶在該圖像上的鼠標事件能夠被JavaScript事件處理 器所捕獲。該JavaScript函數能夠把繪制筆畫相應的點系列發送到一個web服務中。該web服務通過把所有由用戶發送來的點繪制成線同時更新保存 在會話變量中的圖像對象。最后,客戶端向服務端請求一個更新后的圖像。該圖像源是一個HTTP處理器,它把存儲在會話變量中的圖像對象流向客戶端。下面是 該應用程序的主要組成部件。
· Default.aspx
擁有動態圖像和Atlas腳本管理器控件的頁面。
· ScribbleImage.ashx
這是一個HTTP處理器,它實現把存儲在會話變量中的圖像對象轉換為流式數據。
· ScribbleService.asmx
所有的繪畫請求發送到這個web服務中。這個web服務實現圖像修改。
· Scribble.js
該應用程序相應的主要JavaScript代碼駐留在這個文件中,以達到設計與代碼的清晰分離。
· Global.asax
Session_Start和Session_End事件是在Global.asax中處理的。Session_Start用于創建會話變量,而Session_End用于釋放存儲在會話變量中的圖像。
Global.asax
我們從Global.asax文件開始進行我們的編碼過程。
1. 在"Website"菜單上點擊"Add New Item"或按下Ctrl +Shift+A組合鍵。
2. 在"Add New Item"對話框中選擇"Global Application Class"并且點擊ok。你會看到Global.asax文件被自動創建。
3. 一開始,我們導入System.Drawing命名空間。這只要在上面文件的第一行的后面插入下面一行代碼即可:
<%@ Import Namespace="System.Drawing" %>
4. 添加下列代碼到Session_Start函數。
| void Session_Start(object sender, EventArgs e){ Bitmap bmp = new Bitmap(200, 200); using (Graphics g = Graphics.FromImage(bmp)) { g.FillRectangle(new SolidBrush(Color.White),new Rectangle(0, 0, bmp.Width, bmp.Height)); g.Flush(); } Session["Image"] = bmp; } |
這部分代碼創建一個簡單的白色200×200像素的位圖,背景全為白色并把它賦給會話變量Image。
5. Session_End函數應該釋放掉存儲在會話變量中的圖像。
| Bitmap bmp = (Bitmap)Session["Image"]; bmp.Dispose(); |
6. 從"Website"菜單中選擇"Add Reference"。
7. 在"Add Reference"對話框中選擇"System.Drawing"并且點擊OK。
8. 最后,在"Build"菜單下點擊"Build Web Site"或按組合鍵Ctrl+Shift+B來確保沒有構建錯誤。
| ScribbleImage.ashx |
這個web處理器用于把存儲在會話變量中的圖像數據流回客戶端。
1. 在"WebSite"菜單中點擊"Add New Item"或按下Ctrl+Shift+A。
2. 在"Add New Item"對話框中選擇"Generic Handler",然后把該處理器的名字設置為ScribbleImage.ashx并且點擊OK。
3. 一個web處理器要使用會話變量,它需要實現接口IRequiresSessionState。這是唯一的標記接口并且沒有要重載的方法。如下所示編輯該類的聲明:
| public class ScribbleImage : IHttpHandler, System.Web.SessionState.IRequiresSessionState |
4. 接下來,我們把代碼添加到Proce***equest方法。
| public void Proce***equest (HttpContext context){ context.Response.ContentType = "image/png"; context.Response.Cache.SetNoStore(); context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.Cache.SetExpires(DateTime.Now); context.Response.Cache.SetValidUntilExpires(false); System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)context.Session["Image"]; lock(bmp) { using (MemoryStream ms = new MemoryStream()) { bmp.Save(ms, ImageFormat.Png); ms.Flush(); context.Response.BinaryWrite(ms.GetBuffer()); } } } } |
o 第一行設置相應于image/png的響應的ContentType頭。這確保瀏覽器認出該響應是一個png圖像而不是普通HTML代碼。
o 緊接著的四行向瀏覽器指明不應該緩沖這個響應。所有的這四行都是必要的,用于確保該代碼是跨瀏覽器兼容的。我們將在本教程的以后的版本中優化這些代碼。
o 最后,會話變量中的位圖被存儲到一個內存流中,而該內存流的內容被寫到響應中。由于圖像是二進制數據,所以這里使用了BinaryWrite函數。
ScribbleService.asmx
我們有辦法來初始化會話圖像并把該圖像內容轉換成流作為響應。現在,我們需要一些方法來把內容添加到圖像本身。我們期望客戶調用ScribbleService.asmx web服務以把線段添加到圖像上。
1. 在"WebSite"菜單中點擊"Add New Item"或按下Ctrl+Shift+A。
2. 在"Add New Item"對話框中選擇"Web Service",指定名為ScribbleService.asmx并且點擊OK。確保未選定"Place Code in a Separate File"。
3. 通過把下列一行添加到命名空間語句中來導入命名空間System.Drawing:
using System.Drawing;
4. 接下來,我們需要為繪制點定義一個簡單的類。我們不能使用System.Drawing.Point類,因為它是不可以XML串行化的。在后面的內容中, 我們將會看到我們怎樣使用System.Drawing.Point來代替定制的類。現在我們先在ScribbleService類聲明之前添加下面代 碼:
| public class Point{ public int X; public int Y; }; |
5. 最后,我們需要添加一個方法來使用一組給定的點進行繪制。我們把一個web方法Draw添加到我們的web服務。
| [WebMethod(EnableSession = true)] public void Draw(Point[] points){ Image scribbleImage = (Image)Session["Image"]; lock(scribbleImage) { using (Graphics g = Graphics.FromImage(scribbleImage)) using(Pen p = new Pen(Color.Black, 2)) { if (points.Length > 1) { int startX = points[0].X; int startY = points[0].Y; for (long i = 1; i < points.Length; i++) { g.DrawLine(p, startX, startY, points[i].X, points[i].Y); startX = points[i].X; startY = points[i].Y; } } } } } |
o 屬性WebMethod(EnableSession=true)保證會話變量可從web服務中進行存取。
o 圖像被鎖定以確保并發存取的安全性。
o 繪制本身很簡單,因為它僅是把在points數組中提供的點連接起來。
Scribble.js
我們讓服務器端圖像處理器和服務器端web服務來更新圖像。現在,我們需要創建在scribble應用程序中的客戶端腳本,由它來把來自鼠標動作的點發送到服務器web服務。
1. 點擊在解決方案資源管理器中的ScriptLibrary文件夾。
2. 在"WebSite"菜單中點擊"Add New Item"或按下Ctrl+Shift+A。
3. 在"Add New Item"對話框中選擇"JScript File",指定名字為Scribble.js并且按OK。這將把Scribble.js文件放到ScriptLibrary文件夾下。
4. 然后,我們需要聲明一些全局變量。在scribble的第一個版本中,我們將使用全局變量,但是在以后的版本中我們開始使用JavaScript對象。
| //要被繪制的HTML圖像元素 var image; //圖像源 var originalSrc; //The number of iteration var iter = 0; //點數組 var points = null; |
在一個繪制請求被發送到服務器后,這里的iter變量用來修改圖像的源。在Internet Explorer情況下,設置image.src=image.src的確可以刷新該圖像,但是相同的代碼無法在Firefox中工作。為此,我們需要維 護變量iter,這個變量在每次Draw請求發送到Web服務時加1。我們把重復操作次數添加到originalSrc變量中,這樣瀏覽器認為它需要請求 服務器獲取刷新數據,而不是使用緩沖圖像的方式。
5. 定義函數startStroke,它響應mousedown事件開始一個筆畫。
| function startStroke(){ points = new Array(); window.event.returnValue = false; } |
當一個新筆畫開始時,我們創建一個新的點集合,見上面代碼的第一行。第二行取消該事件的默認行為。當相應于一個圖像的mousedown事件的默認行為將開始一次拖動操作時,這是必需的;這樣以來可以防止激活進一步的事件。
6. 當一個響應于一次mouseup事件或mouseout事件的筆畫結束時,我們需要實際調用web服務。這是在endStroke函數中完成的。
| function endStroke(){ if (!points || points.length < 2) return true; //把點發送到web服務 ScribbleService.Draw(points, onWebMethodComplete, onWebMethodTimeout, onWebMethodError); points = null; window.event.returnValue = false; } |
該函數中唯一讓人感興趣的一行是ScribbleService.Draw(points,onWebMethodComplete, onWebMethodTimeout,onWebMethodError);它異步地調用在ScribbleService.asmx中的web服務方 法Draw。Atlas框架使得這一函數可以自動為我們所用。
7. 當在web服務方法中發生錯誤時,將激活onWebMethodError,而當web方法調用超出定義在Atlas框架中可配置的時限時,onWebMethodTimeout函數被調用。在這個版本中,我們僅向用戶顯示一個帶有錯誤文本的消息框。
| function onWebMethodError(fault){ alert("Error occured:\n" + fault.get_message()); } function onWebMethodTimeout(){ alert("Timeout occured"); } |
當web方法調用成功時,onWebMethodComplete函數被調用;這時需要重新加載圖像。
| function onWebMethodComplete(result, response, context){ //我們需要刷新圖像 var shimImage = new Image(200, 200); shimImage.src = originalSrc + "?" + iter++; shimImage.onload = function(){ image.src = shimImage.src; } } |
我們創建一個Image對象shimImage并且把它的源設置為我們正在繪制的圖像的最原始的源。當圖像對象加載時,我們把在該頁面中的實際HTML圖像元素的源設置為臨時圖像對象的源,這樣做可以避免在替換圖像時產生閃爍現象。
8. 我們需要在mousemove事件期間填充points數組。這是在addPoints函數中實現的。
| function addPoints(){ if (points){ var point = { X : window.event.offsetX,Y : window.event.offsetY}; points.push(point); if (points.length == 3){ endStroke(); points = new Array(); points.push(point); } window.event.returnValue = false; } } |
o 新的點對象被使用事件對象的offsetX和offsetY屬性構建,并隨后被添加到points數組中。offsetX和offsetY屬性給出了相對的鼠標位置,這相當于產生該事件的HTML元素。
o 如果數組的長度達到3,那么我們能夠自動地請求服務器實現一個繪制操作并且重置points數組。這樣以來,用戶在他釋放掉鼠標按鈕前可以看到繪制過程。
9. 最后,我們需要鉤住事件,這是在pageLoad函數中完成的。
| function pageLoad(){ var surface = document.getElementById("drawingSurface"); image = surface.getElementsByTagName("IMG")[0]; originalSrc = image.src; surface.attachEvent(" startStroke); surface.attachEvent(" endStroke); surface.attachEvent(" endStroke); surface.attachEvent(" addPoints); } |
o pageLoad是一個特別函數,當Atlas框架完成加載后它被激活。我們使用this來取代常規的窗口或體(body)加載事件,這樣我們可以確保Atlas已經完成加載。
o 實際要畫的圖像元素被放置在一個具有id drawingSurface的div標簽中。該元素的大小與該圖像的大小相同,這樣我們可以安全地把事件依附到drawingSurface div上面。
Default.aspx
應用程序所需要的單獨組件必須被裝配到Default.aspx頁面中。下面是這個頁面的代碼。
| <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Atlas Scribble Sample</title> </head> <body> <form id="form1" runat="server"> <Atlas:ScriptManager ID="AtlasScriptManager" runat="server" EnableScriptComponents="False" > <Services> <Atlas:ServiceReference Path="ScribbleService.asmx" /> </Services> <Scripts> <Atlas:ScriptReference Path="ScriptLibrary/Scribble.js" /> </Scripts> </Atlas:ScriptManager> <div id="drawingSurface" style="border:solid 1px black;height:200px;width:200px"> <img alt="Scribble" src="ScribbleImage.ashx" style="height:200px;width:200px" galleryimg="false" /> </div> </form> </body> </html> |
這個頁面的最重要的部分是atlas:ScriptManager服務器控件。ScriptManager服務器控件負責為Atlas和任何web服務 代理腳本生成客戶端腳本塊。下面讓我們分析一下Default.aspx頁面中的ScriptManager控件的使用。
1. EnableScriptComponents屬性被設置為false。這生成了一個參考AtlasRuntime.js而不是參考Atlas.js的客 戶端腳本塊。因為我們沒有使用任何Atlas組件或控件,所以在這個版本的scribble教程中我們比較喜歡輕量級版本的Atlas框架。我們把一個服 務參考添加到ScribbleService.asmx web服務。這將為web服務代理生成一個到客戶端腳本的URL參考。
2. 我們也把Scribble.js文件作為另一個腳本參考添加到該服務上。
這把上面所討論的各項功能都聯合到一起,現在你可以編譯和運行該工程了。我鼓勵你看一下實際的由Atlas腳本管理器所生成的客戶端html。
Atlas魔術
下面是Atlas框架為我們所做的:
1. 它允許我們創建web應用程序而不需要為使其跨瀏覽器而付出特殊努力。web服務調用和客戶端事件處理可自動地工作于Internet Explorer和Firefox瀏覽器上。Atlas框架把所需要的JavaScript原型添加到Firefox對象以使其看起來象Internet Explorer對象。Internet Explorer的特定函數,如attachEvent,event.offsetX和event.offsetY都可以應用于Firefox。你可以通 過AtlasCompat.js文件來對此進行進一步分析。
2. 它自動地為Scribble web服務方法創建一個JavaScript代理。該JavaScript代理腳本文件相應于一個ScribbleService.asmx文件擁有 URL ScribbleService.asmx/js。這被添加在web.config文件中的Atlas HTTP模塊所產生。
小結
我們已經看到了如何調用web服務與如何容易地使用Atlas來編寫跨瀏覽器的應用程序。在以后的教程中,我們會看到更多的Atlas客戶端控件與聲明性編程(依賴于用戶反饋!)。
下載并使用源代碼
由于Atlas目前還不是可重發布的,所以我沒把Atlas文件包括到下載的源碼中。要使下載的源碼能夠工作,您需要按以下步驟操作。
1. 你需要從Atlas Web Site下載Atlas。
2. 在下載Atlas空白的工程模板以后,通過菜單命令File-New-Web Site創建一新的網站
3. 把源zip文件展開到新建的工程目錄下以覆蓋任何現有文件。
4. 在"Website"菜單下選擇"Add Existing Item",從網站的根目錄下添加上ScribbleService.asmx和ScribbleImage.ashx,并且從ScriptLibrary文件夾下添加上文件Scribble.js。
5. 構建并運行該網站。
總結
以上是生活随笔為你收集整理的创建基于AJAX技术的Scribble应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7下如何快速打开便笺或便签实用小工
- 下一篇: 开坛第一章