C# Windows Phone App 開發,比較Button 的【Mouse】與【Manipulation】事件觸發時機大全 !

  • 1598
  • 0
  • C#
  • 2015-06-10

一般我們在開發Windows Phone App時,很常會使用Button控制項,來幫助我們設計APP,但若我們要使用到的事件不只是Click這麼簡單時呢?有可能會用到當按下後滑動的事件,而在【Mouse】與【Manipulation】的滑動事件就有所不同了。


本篇文章將引導您了解Button 的【Mouse】與【Manipulation】事件觸發時機。

一般我們在開發Windows Phone App時,很常會使用Button控制項,來幫助我們設計APP,但若我們要使用到的事件不只是Click這麼簡單時呢?有可能會用到當按下後滑動的事件,而在【Mouse】與【Manipulation】的滑動事件就有所不同了。

 

 

本篇文章將引導您了解Button 的【Mouse】與【Manipulation】事件觸發時機。

 

 

首先為什麼要寫這篇文章,其實是因為SUKI在開發專案時使用到了這個功能,

而在反覆的測試與錯誤中終於找出解決方案了,而解決方案在本篇文章裡並不重要,

重要的是Button 的【Mouse】與【Manipulation】事件觸發時機,解決了開發專案上的困難。

 

 

 

首先我們針對按鈕的三大事件來說

 

【觸碰】 【移動】 【離開】

 

而這三大的觸發事件我們很直覺的會使用相對應的

 

【觸碰】: MouseEnter  當手指觸碰到控制項範圍內或手指進入控制項範圍內時會觸發的事件。

【移動】: MouseMove 當以發生【MouseEnter 】事件後,手指又在控制項範圍內移動(連續觸發)。

【離開】: MouseLeave 當以發生【MouseEnter 】事件後,手指離開螢幕或離開觸碰區。

 

 

但是另外三個事件也非常的像

 

【操作開始】              ManipulationStarted 當手指擊點控制項範圍內的區域會觸發的事件。

【當手指開始移動時】 ManipulationDelta 當觸發【ManipulationStarted 】後手指移動時(連續觸發)

【操作結束】              ManipulationCompleted 當觸發【ManipulationStarted 】後手指離開螢幕時。

 

 

我們來實做一次,在Xaml中放入一個Button的控制項,並加入上述的六項事件

【MouseEnter  】【MouseMove 】【MouseLeave 】

【ManipulationStarted 】【ManipulationDelta 】【ManipulationCompleted 】

 

   1:  <Button MouseEnter="Button_MouseEnter" 
   2:          MouseMove="Button_MouseMove"
   3:          MouseLeave="Button_MouseLeave" 
   4:          ManipulationStarted="Button_ManipulationStarted" 
   5:          ManipulationDelta="Button_ManipulationDelta" 
   6:          ManipulationCompleted="Button_ManipulationCompleted"/>

 

必在程式碼內寫入相對應的動作,

因為【ManipulationDelta 】和【MouseMove 】這兩個移動事件會連續的觸發,

為了呈現順序故在程式碼內稍作修改,讓其事件觸發實只顯示一次。

 

   1:   private bool MouseMove = false;
   2:          private bool ManipulationMove = false; 
   3:          private void Button_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
   4:          {
   5:              Debug.WriteLine("Button_MouseEnter");
   6:          }
   7:   
   8:          private void Button_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
   9:          {
  10:              Debug.WriteLine("Button_MouseLeave");
  11:              MouseMove = false;
  12:          }
  13:   
  14:          private void Button_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
  15:          {
  16:              if (!MouseMove)
  17:              {
  18:                  Debug.WriteLine("Button_MouseMove");
  19:                  MouseMove = true;
  20:              }
  21:          }
  22:   
  23:          private void Button_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
  24:          {
  25:              Debug.WriteLine("Button_ManipulationStarted");
  26:          }
  27:   
  28:          private void Button_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
  29:          {
  30:              if (!ManipulationMove)
  31:              {
  32:                  Debug.WriteLine("Button_ManipulationDelta");
  33:                  ManipulationMove = true;
  34:              }
  35:          }
  36:   
  37:          private void Button_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
  38:          {
  39:              Debug.WriteLine("Button_ManipulationCompleted");
  40:              ManipulationMove = false;
  41:          }

 

當我們在控制項範圍內使用手指觸碰控制項,

並滑動後放開時一連串的事件

image

事件觸發的順序如下 :

 

1.【Button_MouseEnter】

2.【Button_ManipulationStarted】

3.【Button_MouseMove】

4.【Button_ManipulationDelta】

5.【Button_ManipulationCompleted】

6.【Button_MouseLeave】

 

 

 

但若我們稍微改變一下手指觸碰的方式,從控制項範圍外開始觸碰,

並移動手指經過控制項,最後離開控制項的範圍,這一串過程中,

完全不會觸發【ManipulationStarted 】【ManipulationDelta 】【ManipulationCompleted 】這三個事件

 

image

 

而觸發的順序如下 :

 

1.【Button_MouseEnter】

2.【Button_MouseLeave】

 

這意味著其實要觸發【Mouse】事件時,一開始是不需要先觸碰到控制項範圍內的,

即只要手指還在螢幕上無論是何處落下,只要經過控制項的範圍內就會觸發【MouseEnter】,

離開控制項範圍時就會觸發【MouseLeave】,所以不是只有當手指離開螢幕時才會觸發這兩個事件,

而且很重要的是若第一次觸碰的點不再控制項內,則該次觸碰不會觸發【MouseMove】事件,

若觸碰的第一點不是再控制項範圍內發生則該次觸碰永遠不會觸發【Manipulation】事件。

 

 

 

 

 

但是若我們再改變觸碰的狀況時,又會有其他的順序產生,我們可以透過下圖,

得知Manipulation事件的觸發點

 

image

 

狀況 A 的順序

不考慮【Mouse】事件的順序

1.【ManipulationStarted 】

2.【ManipulationDelta 】

3.【ManipulationCompleted 】

 

意即必須要再控制項的範圍內擊點就會觸發【ManipulationStarted 】,

且只要觸發了【ManipulationStarted 】事件後,手指只要不離開螢幕都不會觸發【ManipulationCompleted 】

即便是移動過程中有經過其他控制項的範圍內 ! !

 

不考慮【Manipulation】事件的順序

1.【Button_MouseEnter】

2.【Button_MouseMove】

3.【Button_MouseLeave】

 

而全部都考慮的事件順序為

1.【Button_MouseEnter】

2.【Button_ManipulationStarted】

3.【Button_MouseMove】

4.【Button_ManipulationDelta】

5.【Button_ManipulationCompleted】

6.【Button_MouseLeave】

 

狀況 B的順序

不考慮【Mouse】事件的順序

1.【ManipulationStarted 】

2.【ManipulationDelta 】

3.【ManipulationCompleted 】

 

不考慮【Manipulation】事件的順序

1.【Button_MouseEnter】

2.【Button_MouseMove】

3.【Button_MouseLeave】

 

而全部都考慮的事件順序為

1.【Button_MouseEnter】

2.【Button_ManipulationStarted】

3.【Button_MouseMove】

4.【Button_ManipulationDelta】

5.【Button_ManipulationCompleted】

6.【Button_MouseLeave】

所以狀況A和狀控B的事件觸發是一模一樣的!

 

 

接下來要說明的是狀況C,當第一次觸碰時手指的範圍是落在控制項以外,

結束並離開螢幕時的點是在控制項範圍內

 

image

 

狀況C 的順序:

1.【Button_MouseEnter】

2.【Button_MouseMove】

3.【Button_MouseLeave】

 

因為再剛才提到,若第一次觸碰點不在控制項範圍內時,

本次的觸碰事件就永遠不會觸發不會觸發【Manipulation】事件。

 

 

 

綜合上述我們可以很清楚的了解,各個事件觸發的時機,

所以在使用這些按鈕事件時,開發者必須慎選,以免產生一下弔詭無法解決的情況。

 

References : SUKI本人悟出來的

 

文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝
轉載請註明出處,並且附上本篇文章網址 !  感謝。

SUKI

HOLIESTAR