WP7有約(六):AppBarUtils使用指南
WP7有約(六):AppBarUtils使用指南
Written by Allen Lee
沒有你的生活,我開始寫小說,好多畫面好多靈感,我要把稿費都給你。
– 周杰倫, Mine Mine
這節(jié)課的任務(wù)
我們知道,Windows Phone的Application Bar并不支持數(shù)據(jù)綁定,這意味著我們無法像Silverlight的Button控件那樣把Application Bar上的按鈕或者菜單項直接綁到視圖模型的命令屬性。
為了解決這個問題,我們可以借助一些第三方工具包,比如今天我給大家介紹的AppBarUtils,它提供了一組Expression Blend行為,可以實現(xiàn)Application Bar上的按鈕和菜單項的綁定。接下來,我們將會具體看看如何使用這個工具包實現(xiàn)相關(guān)的功能。
首先,假設(shè)我們的應(yīng)用包含了圖1-1所示的Application Bar。
圖 11 Application Bar
其中,add按鈕和clear菜單項分別綁到視圖模型的兩個命令屬性,它們分別負責(zé)把數(shù)據(jù)添加到頁面的ListBox控件里和清空ListBox控件里的內(nèi)容;sync按鈕將會執(zhí)行視圖模型的Sync方法;而statistic菜單項將會打開統(tǒng)計結(jié)果頁面。
在開始之前,你需要到http://appbarutils.codeplex.com/下載AppBarUtils的dll,并在項目里引用它。
按鈕和菜單的命令綁定
在Expression Blend里單擊左邊工具欄上的Assets按鈕打開Assets窗口,選擇Behaviors類別,然后從右邊把AppBarItemCommand拖到Objects and Timeline面板的[PhoneApplicationPage]上,如圖2-1所示。
圖 21 添加AppBarItemCommand
看到這里,你可能會問,為什么是拖到[PhoneApplicationPage]上呢?因為Application Bar上的按鈕和菜單項并非依賴對象,Expression Blend的行為無法和它們關(guān)聯(lián),而在Windows Phone的應(yīng)用程序唯一能夠訪問Application Bar的地方就是頁面,所以我們需要把AppBarItemCommand拖到[PhoneApplicationPage]上。
重復(fù)上述步驟添加一個AppBarItemCommand。現(xiàn)在我們有兩個AppBarItemCommand,分別用于add按鈕和clear菜單項。
在Objects and Timeline面板上選中第一個AppBarItemCommand,然后在Properties面板上把Id屬性設(shè)為add,如圖2-2所示。
圖 22 設(shè)置Id屬性
因為AppBarItemCommand是根據(jù)Text屬性的值查找Application Bar上的按鈕的,所以Id屬性的值必須匹配Text屬性的值。
接著,切換到XAML模式,把AppBarItemCommand的Command屬性綁到視圖模型的對應(yīng)的命令屬性,如代碼2-1所示。
代碼 21 設(shè)置Command屬性的綁定
<AppBarUtils:AppBarItemCommand Id="add" Command="{Binding AddCommand}"/>
看到這里,你可能會問,為什么不直接在Properties面板上設(shè)置Command屬性的綁定呢?這是因為Expression Blend對Behavior的ICommand類型的屬性做了特殊處理,如上面的圖2-2所示,這使得Command屬性看起來不像普通屬性,右邊也沒有Advanced options按鈕,所以無法打開數(shù)據(jù)綁定對話框。
至于clear菜單項,我們需要在Properties面板上把Id和Type兩個屬性的值分別設(shè)為clear和MenuItem,如圖2-3所示。
圖 23 設(shè)置Id和Type兩個屬性
需要說明的是,Type屬性是用來區(qū)分Application Bar上的按鈕和菜單項這兩種類型的,它的默認值是Button,因此,當你在按鈕上使用AppBarItemCommand時,你不需要設(shè)置這個屬性的值。
最后是Command屬性的綁定,和前面一樣,我們需要切換到XAML模式設(shè)置綁定表達式,如代碼2-2所示。
代碼 22 設(shè)置Command屬性的綁定
<AppBarUtils:AppBarItemCommand Type="MenuItem" Id="clear" Command="{Binding ClearCommand}"/>
使用Expression Blend SDK的行為
你知道嗎,Expression Blend SDK提供了許多有用的行為,其中一個是CallMethodAction,它可以用來執(zhí)行指定對象的指定方法,顯然非常適合我們的sync按鈕,不過,它需要和Trigger一起工作,而Expression Blend SDK并未提供適用于Application Bar的Trigger,怎么辦?這個時候就輪到AppBarItemTrigger出場了。
打開Assets窗口,選擇Behaviors類別,然后從右邊把CallMethodAction拖到Objects and Timeline面板的[PhoneApplicationPage]上,如圖3-1所示。
圖 31 添加CallMethodAction
確保CallMethodAction處于選中狀態(tài),在Properties面板上TriggerType右邊的New按鈕,如圖3-2所示。
圖 32 單擊New按鈕
在彈出的Select Object對話框里選擇AppBarItemTrigger,如圖3-3所示,然后單擊OK按鈕關(guān)閉對話框。
圖 33 選擇AppBarItemTrigger
此時,Trigger的相關(guān)屬性將會換成AppBarItemTrigger的,把Id屬性的值設(shè)為sync,如圖3-4所示。
圖 34 AppBarItemTrigger的屬性
至于CallMethodAction本身的屬性,我們只需把TargetObject屬性綁到指定對象,然后把MethodName屬性的值設(shè)為指定方法的名字就行了。
頁面導(dǎo)航行為
有了AppBarItemTrigger,我們就可以使用Expression Blend SDK的NavigateToPageAction為Application Bar實現(xiàn)打開頁面的操作了,當然,更簡單的辦法是直接使用AppBarItemNavigation,它的用法和AppBarItemCommand類似,只是Command屬性換成了TargetPage屬性。
如果你希望在URI里包含查詢字符串,而參數(shù)的值又是綁到視圖模型的屬性的,那么,你可以試試NavigateWithQueryStringAction。
打開Assets窗口,選擇Behaviors類別,然后從右邊把NavigateWithQueryStringAction拖到Objects and Timeline面板的[PhoneApplicationPage]上,如圖4-1所示。
圖 41 添加NavigateWithQueryStringAction
確保NavigateWithQueryStringAction處于選中狀態(tài),在Properties面板上Trigger改為AppBarItemTrigger,然后把Id、Type和TargetPage三個屬性的值分別改為statistic、MenuItem和/StatisticPage.xaml,如圖4-2所示。
圖 42 設(shè)置相關(guān)屬性
假設(shè)我們希望包含的查詢字符串是"hitcount=XX&timecount=YY",其中,XX和YY分別來自視圖模型的HitCount和TimeCount兩個屬性,那么,我們可以通過NavigateWithQueryStringAction的Parameters屬性進行設(shè)置。
在Properties面板上單擊Parameters屬性右邊的Edit items in this collection按鈕,在彈出的Parameter Collection Editor對話框里單擊Add another item按鈕添加一個參數(shù),把Field屬性的值設(shè)為hitcount,把Value屬性綁到視圖模型的HitCount屬性,如圖4-3所示。
圖 43 添加參數(shù)
用同樣的辦法添加一個timecount參數(shù),并把它的Value屬性綁到視圖模型的TimeCount屬性。
根據(jù)上述設(shè)置,NavigateWithQueryStringAction將會為我們創(chuàng)建一個這樣的URI:/StatisticPage.xaml?hitcount=9&timecount=13(假設(shè)用戶單擊statistic菜單項時,HitCount和TimeCount兩個屬性的值分別為9和13)。
由于NavigateWithQueryStringAction是一個TriggerAction,這意味著它的用途并不限于Application Bar,你可以通過Expression Blend SDK的EventTrigger把它用到Silverlight的Button控件(或者其它控件)上。
最后,如果你需要的只是一個簡單的后退,你可以使用GoBackAction。和NavigateWithQueryStringAction一樣,你可以通過AppbarItemTrigger把它用到Application Bar上,也可以通過EventTrigger把它用到Silverlight的Button控件(或者其它控件)上。
綁定啟用狀態(tài)和顯示文字
有些時候,你可能希望Application Bar上的按鈕和菜單項可以根據(jù)某些條件自動調(diào)整啟用狀態(tài),比如說,當頁面的ListBox控件里有內(nèi)容時,sync按鈕才可用,否則,它應(yīng)該處于禁用狀態(tài)。
AppBarItemTrigger提供了一個IsEnabled依賴屬性,當我們把它綁到視圖模型的某個bool類型的屬性時,前者會監(jiān)聽后者的更改,然后把修改后的值反映到Application Bar上的按鈕或者菜單項的IsEnabled屬性。
如果你使用的是AppBarItemCommand,你可以通過ICommand.CanExecute方法的返回值指定啟用/禁用狀態(tài),并在狀態(tài)發(fā)生更改的時候觸發(fā)CanExecuteChanged事件,剩下的事情AppBarItemCommand會幫你處理好的。
至于Application Bar上的按鈕和菜單項的顯示文字,你也可能希望實現(xiàn)綁定,這種需求通常出現(xiàn)在多語言支持的應(yīng)用里,這個時候,你可以把AppBarItemTrigger的Text依賴屬性綁到資源對象的某個屬性,前者會監(jiān)聽后者的更改,然后把修改后的值反映到Application Bar上的按鈕或者菜單項的Text屬性。如果你使用的是AppBarItemCommand或者AppBarItemNavigation,你也可以通過它們的Text依賴屬性實現(xiàn)同樣的效果。
看到這里,有些同學(xué)可能會擔(dān)心Id和Text兩個屬性打起架來,放心吧,它們不會的。雖然它們最終都是關(guān)聯(lián)到Application Bar上的按鈕或者菜單項的Text屬性,但它們發(fā)生作用的時間是不同的。Id屬性只在行為初始化的時候用來查找Application Bar上的按鈕或者菜單項,一旦找到,Id屬性就會功成身退了,從此刻開始,Text屬性將會派上用場,它會密切關(guān)注綁定源,并把更新反映到Application Bar上的按鈕或者菜單項的Text屬性。
下課了……


浙公網(wǎng)安備 33010602011771號