Essential Silverlight翻譯連載(5、6章)
第5章 互動和事件處理
Silverlight互動
宣告式語言表示XAML提供了很多可能,包括建立所有型別的形狀(見第4章),動畫元素(見第6章),播放聲音影片資料(見第7章)。但如果您在Silverlight中加入少量JavaScript程式碼,將會釋放出它的真實的力量。JavaScript本身是一個強大的語言,但開發者也可以在Silverlight中使用JavaScript API。本書第三部分,特別是第8章,將更詳細地講述JavaScript訪問。雖然本書主要關注的是宣告式語言XAML,但沒有指令碼,很多事將不能做。
這一章解釋Silverlight事件處理。特別是什麼是事件,怎麼獲取和處理它們。大部份的事件處理程式碼都以“XAML code-behind”的方式存在於Filename.xaml.js檔案中。從技術手段上來說,javaScript程式碼可以放置在任何JavaScript檔案中,只需要在主HTML檔案中透過<script>標籤來引用就行了。如果在.xaml.js檔案中使用觸發XAML的JavaScript程式碼,而在html.js檔案中加入觸發JavaScript程式碼的HTML頁面,就可以使應用程式更易於打包和開發。
大部份的檔案清單最少有三個檔案---HTML檔案,XAML檔案,一個或多個JavaScript檔案。部分檔案的內容總是很相似,例如createSilverlight()方法的程式碼。從下一個例子開始,我們將調整內含的XAML檔案的,將不再給出createSilverlight()方法的程式碼。就好象之前沒有給出HTML檔案的程式碼一樣。儘管如此,您也可以在本書配套的程式碼()中找到例子的完整程式碼。
提示:如果對HTML,XAML和JavaScript檔案的作用有任何疑問,請複習第2章的基本概念。
事件和事件處理
Silverlight事件是當Silverlight應用程式執行時會發生某些事情。這些事情可能是滑鼠單擊,滑鼠移動,鍵盤輸入,應用程式接受或失去焦點,應用程式開始完全載入或是其他類似的事情。所有事件依賴於一個物件,這樣不管滑鼠指標在矩形之上還是文字之上,單擊時都會有所不同。
Silverlight現在支援超過24個事件,將來的版本可能會更多。本章只關心最重要的一些事件,並提供之前不曾提及到的事件的相關背景知識。
事件處理是一個程式碼塊,在事件發生(或叫觸發)時被執行。這裡所說的事件和事件處理和HTML中的JavaScript事件概念非常接近。
宣告事件處理
有兩種途徑給一個事件分配一個事件處理---使用宣告式方法或使用程式碼。讓我們從第一個選項開始,並使用滑鼠事件。Silverlight支援幾種滑鼠事件,其中之一是使用者單擊滑鼠左鍵時發生的MouseLeftButtonDown(在滑鼠被釋放前發生)。
讓我們回顧一下第二章的第一個例子“Hello World”,它包含了三個元素,外層的<Canvas>,一個<Rectangle>和一個<TextBlock>。我們給這三個元素新增事件處理。新增一個事件處理非常容易:新增一個和事件名稱相同的屬性(在此例中,使用LeftMouseButtonDown而不是JavaScript中的OnLeftMouseButtonDown)。這個屬性的值是JavaScript的方法名稱。當事件觸發時將呼叫這個方法一次。例5-1顯示了這個包括三個事件處理的XAML檔案:
例5-1 使用事件處理,XAML檔案(MouseClick.xaml)
<Canvas xmlns=""
xmlns:x=""
MouseLeftButtonDown="mouseClick">
<Rectangle Width="200" Height="75" Stroke="Orange" StrokeThickness="15"
MouseLeftButtonDown="mouseClick" />
<TextBlock FontFamily="Arial" FontSize="32" Canvas.Left="30" Canvas.Top="20"
Foreground="Black" Text="Silverlight"
MouseLeftButtonDown="mouseClick" />
Canvas>
JavaScript事件處理方法存在於MouseClick.js.xaml檔案內,它象ASP.NET事件處理方法一樣接收兩個引數:
sender
接收到事件的那個物件的引用,並會呼叫事件處理。
eventArgs
事件的資訊,例如,當處理一個滑鼠事件時,可以得到當前滑鼠的位置。簡單的事件處理方法所做的是顯示哪個元素觸發了事件。為了實現這個功能,需要使用到sender引數的字串表達。例如,當<TextBlock>元素觸發了事件,sender.toString()所返回的是TextBlock。例5-2中的.xaml.js檔案中的“XAML code-behind”程式碼演示了這項功能。
例5-2 使用事件處理,XAML JavaScript檔案(MouseClick.xaml.js)
function mouseClick(sender, eventArgs)
{
alert('Ouch, says ' + sender.toString() + 'l');
}
現在,當您單擊文字塊時,將會彈出兩個JavaScript視窗:一個是文字塊的,另一個是canvas的(圖5-1)。這叫做“事件浮升機制”。無論何時,當一個元素接收到一個事件,它會把事件向上傳播到父節點(在本例中,<TextBlock>把事件傳播給<Canvas>)。如果父節點本身還有父節點,事件還會繼續向上傳播。這種機制和JavaScript在Explorer瀏覽器裡的事件機制很相似,它經常用於巢狀的XAML結構,並且需要為幾個物件新增事件處理。當然例5-1的這種機制是很少使用的,一般只給一個元素新增事件處理。
譯者注:由於使用了XAML的程式碼隱藏檔案,所以這個例子需要的是四個檔案,除了前面一章所講的三個檔案外,還多了一個xaml.js檔案。例5-2所演示的就是這個檔案。這樣就需要在html檔案內多加一行程式碼引用這個檔案。在html檔案中的
程式碼後面新增一行
這樣就可以正常執行程式了。後面的例子也是這樣處理。
當您想改變觸發事件的物件時,把Sender屬性賦給事件處理方法非常方便。 一般的規則是把每個屬性(例如
例5-3 改變事件目錄屬性,XAML檔案(MouseHover.xaml)
<Canvas xmlns=""
xmlns:x="">
<Rectangle Width="200" Height="75" Stroke="Orange" StrokeThickness="15" />
<TextBlock FontFamily="Arial" FontSize="32" Text="Silverlight"
Canvas.Left="30" Canvas.Top="20"
Foreground="LightGray" MouseEnter="high" MouseLeave="low" />
Canvas>
XAML的程式碼隱藏的JavaScript檔案(例5-4)訪問sender引數並設定foreguound屬性。結果顯示為文字首先顯示為亮灰色,但當滑鼠移動到它上面時,它會變為黑色。當滑鼠離開文字顯示區域時,它又變回為亮灰色。圖5-2顯示了文字的兩種狀態。
例5-4 改變事件目標屬性,XAML JavaScript檔案(MouseHover.xaml.js)
function high(sender, eventArgs) {
sender.Foreground = 'Black';
}
function low(sender, eventArgs) {
sender.Foreground = 'LightGray';
}
事件偵聽
第二種是使用程式碼的方法:使用事件偵聽把一個事件處理賦給一個事件。您可以安排一段程式碼“偵聽”是否有事件發生。如果發生了,將會進行適當地處理。宣告事件處理的主要優勢是很容易移除一個事件偵聽。不利條件是事件偵聽並非自動生成的,特別對於一些有很強的HTML背景的開發人員。但當您第一次使用它,並在程式中使用它根本不困難。
讓我們開始一段XAML程式碼。正如您所見,並沒有專門針對單擊事件的事件處理屬性。好,這有另外一個重要的事件:Loaded。一個元素只會觸發一次Loaded事件,如例5-5,整個XAML檔案被完全載入後,我們使用這個事件建立實際的事件偵聽。
例5-5 使用事件偵聽,XAML檔案(MouseClickListener.xaml)
<Canvas xmlns=""
xmlns:x=""
Loaded="canvasLoaded">
<Rectangle Width="200" Height="75" Stroke="Orange" StrokeThickness="15" />
<TextBlock FontFamily="Arial" FontSize="32" Canvas.Left="30" Canvas.Top="20"
Foreground="Black" Text="Silverlight"
x:Name="ClickTarget"/>
Canvas>
建立事件偵聽
時間證明一切,我們來看看下面這段建立事件偵聽的JavaScript程式碼:
window.onload = function() {
// 這裡建立事件偵聽
}
當HTML頁面標記過完全載入時,頁面的Load事件將會被觸發一次。當然這並不代表所有相關檔案包括JavaScript類庫和XAML檔案已經被完全載入。當在您的本地計算機上測試它時,它可能不會被執行,因為檔案是從速度很快的硬碟上載入的。然而Internet可能會有嚴重的延遲,所以您不能依賴於這種方法。這也是為什麼使用根元素的Loaded事件來初始化Silverlight應用程式並不常用的原因之一。
但現在對於事件偵聽來說,首先你不得不尋找跟事件偵聽關聯的元素。在例5-5中我們應該注意到,
我們可以訪問XAML中的元素。需要記住,事件處理方法自動接收一個sender的引用做為他們的第一個引數。所以我們可以使用sender和它的findName()方法來訪問文字塊:
function canvasLoaded(sender, eventArgs) {
var textblock = sender.findName('ClickTarget');
}
一旦獲得了文字塊(或其他元素),就可以把事件處理賦給它。完成這個任務的方法是addEventListener(),它有兩個引數:
1. 事件的名稱
2. 事件處理,也可以是一個方法的引用,或一個匿名方法
textblock.addEventListener('MouseLeftButtonDown',mouseClick);
以上所執行的是實際的事件處理,它輸出兩個元素,觸發的事件和它的名稱。例5-6顯示了JavaScript檔案的完整程式碼,圖5-3是瀏覽器中的輸出效果。
例5-6 使用事件偵聽,XAML JavaScript檔案(MouseClickListener.xaml.js)
function canvasLoaded(sender, eventArgs) {
var textblock = sender.findName('ClickTarget');
textblock.addEventListener(
'MouseLeftButtonDown',
mouseClick);
}
function mouseClick(sender, eventArgs) {
alert('Ouch, says ' + sender.toString() + '“'+ sender.name + '”!');
}
圖5-3 使用程式給事件偵聽賦值
移除事件偵聽將會使它被“Mouse Position”的程式碼段所覆蓋。
滑鼠事件
Silverlight 1.0支援5個滑鼠事件,其中三個前面已經介紹過:
MouseEnter
滑鼠指標移動到物件顯示區域內
MouseLeave
滑鼠指標從物件顯示區域離開
MouseMove
滑鼠移動
MouseLeftButtonDown
滑鼠左鍵按下
MouseLeftButtonUp
滑鼠左鍵單擊並釋放
這些事件是自解釋的,但應該解釋一下MouseLeftButtonDown和MouseLeftButtonUp之間的不同之處。單使用者在某元素上單擊滑鼠,首先會觸發MouseLeftButtonDown事件,然後是MouseLeftButtonUp事件。所以滑鼠單擊是在MouseLeftButtonUp事件被觸發之後才完成。實際上它們之間只有在一種情況下才會有區別:使用者把滑鼠指標移動到元素之上,按下滑鼠按鈕不放,再次移動滑鼠離開元素。當您使用MouseLeftButtonUp事件,它將不會被觸發,這符合一些場影的需要(如按鈕事件),但不符合別一些場影的需要(如滑鼠拖動)。
提示:滑鼠事件針對向量圖格式SVG的機制如支援三種滑鼠事件:按鈕按下,按鈕釋放,按鈕單擊。
滑鼠位置
當您捕獲一個滑鼠事件,可能想知道滑鼠指標當前的位置。關於“在哪裡”的問題前面已經回答過,就是物件之上,更具體的問題是“在哪個位置?”。這一點可以轉而關注事件處理方法的第二個引數eventArgs。它提供了這些資訊,並支援getPosition()方法。
getPosition()方法支援任意的XML元素做為引數。如果設定了它,getPosition()方法將得到滑鼠相對於給定元素的座標。否則,將得到一個絕對座標(例如,您沒有提供引數或引數是一個null值)。
getPosition()方法的返回值是一個帶有兩個屬性x和y的物件,它代表了滑鼠指標水平和垂直位置。在Web中,原點表示的是左上角的位置。
例5-7所包含的XAML標記跟蹤了滑鼠的移動。注意<TextBlock>屬性是如何用於顯示滑鼠指標位置的。另外還需注意主canvas的Loaded事件所執行的方法是canvasLoaded()。
例5-7 顯示滑鼠位置,XAML檔案(MousePosition.xaml)
<Canvas xmlns=""
xmlns:x=""
Loaded="canvasLoaded">
<Rectangle Width="200" Height="75" Stroke="Orange" StrokeThickness="15" />
<TextBlock FontFamily="Arial" FontSize="28" Canvas.Left="25" Canvas.Top="25"
Foreground="Black"
Text="X: ?? Y: ??" x:Name="MousePosition" />
Canvas>
JavaScript程式碼的任務是當滑鼠移動時確定並輸出當前滑鼠指標的位置。相關的事件名稱是MouseMove,想象中事件偵聽的程式碼應該如下:
function canvasLoaded(sender, eventArgs) {
sender.addEventListener(
'MouseMove',
//事件偵聽的引用或程式碼);
}
現在所需做的事只是寫事件偵聽,這裡我們將使用匿名方法。它使用getPosition()方法確定滑鼠位置並寫入文字框中。例5-8是完整的JavaScript程式碼,圖5-4可以看到它在瀏覽器中的效果。
例5-8 顯示滑鼠位置,XAML JavaScript檔案(MousePosition.xaml.js)
function canvasLoaded(sender, eventArgs) {
sender.addEventListener('MouseMove',
function(sender, eventArgs) {
var x = eventArgs.getPosition(null).x;
var y = eventArgs.getPosition(null).y;
sender.findName('MousePosition').text=
'X: '+ x + ' Y: ' + y;
}
);
}
圖5-4 顯示當前滑鼠位置
前面曾經提到過,您可以移除事件偵聽。為此您可以在繫結了事件偵聽的物件上呼叫removeEventListener()方法。第一個引數還是事件,但第二個引數可能會讓您感到吃驚,它是事件偵聽的引用(因為您可以在一個事件上繫結多個事件偵聽)。您可以透過在呼叫addEventListener()方法時儲存其返回值來得到這個引用。
為了示範這種機制,我們再次使用滑鼠移動,但這一次在單擊文字時顯示。我們開始於前面的例5-7中的XAML標記,但檔名改為MousePositionToggle.xaml。JavaScript程式碼也做了很多改變。首先定義兩個全域性變數。一個用於存放被繫結的事件處理,另一個是一個布林值,用於用於通知指令碼當前是否跟蹤滑鼠位置。
var
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16396910/viewspace-1030334/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Essential Silverlight翻譯連載(3、4章)
- docker官方文件翻譯5Docker
- 【翻譯】.NET 5 Preview5釋出View
- 轉載10gocp翻譯Go
- 有道翻譯軟體下載地址
- 【翻譯】.NET 5 Preview8釋出View
- 【翻譯】.NET 5 Preview7釋出View
- 【翻譯】.NET 5中的效能改進
- 【翻譯】.NET 5 RC1釋出
- 5 Java NIO Scatter 與Gather-翻譯Java
- 【翻譯】安卓架構元件(5)-ViewModel安卓架構元件View
- Angular 5 開發一個有道翻譯Angular
- 轉載:翻譯的寧靜工程 (節選)
- 翻譯出版那點事兒【轉載】
- Essential C++C++
- 翻譯
- Yurii談翻譯(五)怎樣翻譯更地道:so…that…的翻譯
- 如何完成中文翻譯日文線上翻譯
- Yurii談翻譯(四)怎樣翻譯更地道:翻譯如鋪路
- Yurii談翻譯(九)怎樣翻譯更地道:冠詞a的翻譯
- Yurii談翻譯(十)怎樣翻譯更地道:最高階的翻譯
- 翻譯的未來:翻譯機器和譯後編譯編譯
- 【風農翻譯】開始畫畫素畫 #5
- 基於PYQT5的截圖翻譯工具QT
- Ubuntu安裝劃詞翻譯軟體Goldendict 單詞翻譯 句子翻譯UbuntuGo
- Yurii談翻譯(六)怎樣翻譯更地道:“as somebody said…”的翻譯AI
- Yurii談翻譯(十三)怎樣翻譯更地道:It is…that…句型諺語的翻譯
- Yurii談翻譯(十四)怎樣翻譯更地道:否定句的翻譯
- 蝴蝶書-task2: 文字推理、摘要、糾錯 transformers實現翻譯 OpenAI翻譯 PyDeepLX翻譯 DeepLpro翻譯ORMOpenAI
- Nginx翻譯Nginx
- [翻譯] TransitionKit
- 翻譯篇
- OllDbg翻譯LLDB
- OpenCV翻譯專案總結二——Mat翻譯OpenCV
- 【翻譯】The State of Open Banking -5. COLLABORATION STRATEGIES
- (翻譯)2016美國數學建模MCM A題(連續型)翻譯:A Hot Bath 一個熱水澡BAT
- [翻譯 EF Core in Action 2.4] 載入相關資料
- 文件翻譯器怎麼用?如何翻譯Word文件?