在開發Windows Phone 7應用程式時,偶爾會需要實現帶有兩種狀態的按鈕,點擊按鈕即可在兩種狀態間進行切換,且各狀態對應的外觀也有所不同。其實SDK裡預設內建的CheckBox控制項及Silverlight Toolkit裡提供的ToggleSwitch控制項都能在某種程度上滿足上述需求。只是它們的外觀相對固定,並不容易定製。那麼,今天就向大家介紹一款新的自訂控制項,稱之為:SwitchButton。
首先,我們來看一看實際啟動並執行效果:
在點擊SwitchButton時,按鈕的外觀平滑地從左邊的狀態過渡到右邊的狀態,並且在代碼中觸發其Checked/Unchecked事件,並即時更新其IsChecked屬性為true或false。
下載代碼
接下來,我們就開始動手實現它。
第一步:編寫自訂控制項類
製作一個自訂的控制項,首先要從編寫控制項的類開始。儘管我們要做的SwitchButton與CheckBox有所區別,但其主要的行為和屬性應該是與CheckBox相一致的。因此,我們不妨先查看一番CheckBox的定義。在VisualStudio裡通過追溯基類我們可以瞭解到,CheckBox是繼承自System.Windows.Controls.Primitives命名空間下的ToggleButton類。進一步查看ToggleButton類的定義,可以看到一個帶有狀態的按鈕所需要的大部分屬性和事件,都是在這裡進行定義的。既然如此,那我們的SwitchButton類也理所當然地要繼承ToggleButton類。
在Visual Studio裡,建立(或開啟)一個 Windows Phone 7 項目,然後添加一個SwitchButton類。代碼如下:
public class SwitchButton : ToggleButton
{
public static readonly DependencyProperty SwitchOnImageSourceProperty =
DependencyProperty.Register(
"SwitchOnImageSource",
typeof(ImageSource),
typeof(SwitchButton),
null);
public ImageSource SwitchOnImageSource
{
get { return (ImageSource)GetValue(SwitchOnImageSourceProperty); }
set { SetValue(SwitchOnImageSourceProperty, value); }
}
public static readonly DependencyProperty SwitchOffImageSourceProperty =
DependencyProperty.Register(
"SwitchOffImageSource",
typeof(ImageSource),
typeof(SwitchButton),
null);
public ImageSource SwitchOffImageSource
{
get { return (ImageSource)GetValue(SwitchOffImageSourceProperty); }
set { SetValue(SwitchOffImageSourceProperty, value); }
}
}
我們在SwitchButton類中聲明了兩個屬性,分別是:SwitchOnImageSource和SwitchOffImageSource。這兩個屬性用來指定SwitchButton控制項在處於兩種狀態時所需要顯示的外觀圖片。關於控制項屬性的聲明,請查看有關 DependencyProperty 的更多資訊。
第二步:設計自訂控制項的外觀和行為
在Phone Page中拖放一個SwitchButton控制項。然後用[按右鍵]->[Edit Template]->[Edit a copy]的方式,產生一個模板。接下來,我們就開始編輯這個模板。
(關於在Expression Blend裡設計自訂控制項範本的詳細步驟,請參考我的另外一篇文章:
Windows Phone 7 定製控制項 - ImageButton)
這裡僅針對SwitchButton特有的內容進行說明。
SwitchButton的模板繼承自ToggleButton控制項的模板,具有三個VisualStateGroup,分別是:CommonStates、CheckStates、FocusStates。我們主要關心的是CheckStates狀態組下的三個VisualState,分別是:Checked、Unchecked及Indeterminate。其中,Indeterminate狀態對應的是“不確定”狀態,即在某些特殊應用情境中,需要實現三種狀態的按鈕時才用得到。在本例中,我們不去考慮它。
簡單說明一下設計思路:在SwitchButton處於Checked狀態時,我們需要它顯示某個圖片,而在它處於Unchecked狀態時,我們需要它顯示另一個圖片。
OK,下面介紹具體操作步驟:
操作2.1:
既然先後需要切換兩個圖片,那麼就將控制項範本根目錄中Grid的所有子控制項刪除,並且加上兩個Image控制項,分別命名為:imageOn和imageOff。
操作2.2:
選中imageOn控制項,在屬性面板中,點擊 [Source] 屬性右側的小方塊(Advanced Options),設定 Template Binding 為SwitchOnImageSource。同樣地,將imageOff控制項的Source綁定到SwitchOffImageSource屬性。這一步操作,是將兩個 Image控制項的圖片資源綁定到我們在一開始聲明的兩個屬性上,從而實現在實際使用 SwitchButton 控制項的地方,根據需求來指定不同的圖片,達到重複使用的目的。
提示:
兩個狀態所對應的圖片應遵循“大同小異”的原則,即:兩張圖的尺寸及配色基本一致,只有某一局部在位移、尺寸或明暗度上發生小幅變化。有些朋友或許會擔心“變化不夠大,怕使用者忽略”,其實不然。請記住,使用者的實現集中一處時,對哪怕一個像素的變化都是敏感的。
操作2.3:
在預設狀態下(即:在States面板中選中Base狀態的情況下),將imageOff的Opacity值設定為0%,即不可見。
操作2.4:
在States面板中,選中Unchecked狀態,將imageOn的Opacity設定為0%,而imageOff的Opacity設定為100%。然後將CheckStates下的Default transition設定為一個合理時間長度,例如0.3秒,從而使得狀態間的切換過渡更加自然。
第三步:使用自訂控制項
在PhonePage中,放置一個SwitchButton控制項並選中,然後在屬性面板的Miscellaneous地區中,找到SwitchOnImageSource屬性及SwitchOffImageSource屬性。分貝為它們設定不同的圖片,以代表兩個狀態。
運行程式,在介面中反覆點擊SwitchButton按鈕,會看到它在兩個狀態間進行切換。
OK。至此我們就完成了定製SwitchButton控制項。
下載代碼