WP7有约(六):AppBarUtils使用指南
written by allen lee
没有你的生活,我开始写小说,好多画面好多灵感,我要把稿费都给你。
– 周杰伦, mine mine
这节课的任务
我们知道,windows phone的application bar并不支持数据绑定,这意味着我们无法像silverlight的button控件那样把application bar上的按钮或者菜单项直接绑到视图模型的命令属性。
为了解决这个问题,我们可以借助一些第三方工具包,比如今天我给大家介绍的appbarutils,它提供了一组expression blend行为,可以实现application bar上的按钮和菜单项的绑定。接下来,我们将会具体看看如何使用这个工具包实现相关的功能。
首先,假设我们的应用包含了图1-1所示的application bar。
图 11 application bar
其中,add按钮和clear菜单项分别绑到视图模型的两个命令属性,它们分别负责把数据添加到页面的listbox控件里和清空listbox控件里的内容;sync按钮将会执行视图模型的sync方法;而statistic菜单项将会打开统计结果页面。
在开始之前,你需要到下载appbarutils的dll,并在项目里引用它。
按钮和菜单的命令绑定
在expression blend里单击左边工具栏上的assets按钮打开assets窗口,选择behaviors类别,然后从右边把appbaritemcommand拖到objects and timeline面板的[phoneapplicationpage]上,如图2-1所示。
图 21 添加appbaritemcommand
看到这里,你可能会问,为什么是拖到[phoneapplicationpage]上呢?因为application bar上的按钮和菜单项并非依赖对象,expression blend的行为无法和它们关联,而在windows phone的应用程序唯一能够访问application bar的地方就是页面,所以我们需要把appbaritemcommand拖到[phoneapplicationpage]上。
重复上述步骤添加一个appbaritemcommand。现在我们有两个appbaritemcommand,分别用于add按钮和clear菜单项。
在objects and timeline面板上选中第一个appbaritemcommand,然后在properties面板上把id属性设为add,如图2-2所示。
图 22 设置id属性
因为appbaritemcommand是根据text属性的值查找application bar上的按钮的,所以id属性的值必须匹配text属性的值。
接着,切换到xaml模式,把appbaritemcommand的command属性绑到视图模型的对应的命令属性,如代码2-1所示。
代码 21 设置command属性的绑定
<appbarutils:appbaritemcommand id="add" command="{binding addcommand}"/>
看到这里,你可能会问,为什么不直接在properties面板上设置command属性的绑定呢?这是因为expression blend对behavior的icommand类型的属性做了特殊处理,如上面的图2-2所示,这使得command属性看起来不像普通属性,右边也没有advanced options按钮,所以无法打开数据绑定对话框。
至于clear菜单项,我们需要在properties面板上把id和type两个属性的值分别设为clear和menuitem,如图2-3所示。
图 23 设置id和type两个属性
需要说明的是,type属性是用来区分application bar上的按钮和菜单项这两种类型的,它的默认值是button,因此,当你在按钮上使用appbaritemcommand时,你不需要设置这个属性的值。
最后是command属性的绑定,和前面一样,我们需要切换到xaml模式设置绑定表达式,如代码2-2所示。
代码 22 设置command属性的绑定
<appbarutils:appbaritemcommand type="menuitem" id="clear" command="{binding clearcommand}"/>
使用expression blend sdk的行为
你知道吗,expression blend sdk提供了许多有用的行为,其中一个是callmethodaction,它可以用来执行指定对象的指定方法,显然非常适合我们的sync按钮,不过,它需要和trigger一起工作,而expression blend sdk并未提供适用于application bar的trigger,怎么办?这个时候就轮到appbaritemtrigger出场了。
打开assets窗口,选择behaviors类别,然后从右边把callmethodaction拖到objects and timeline面板的[phoneapplicationpage]上,如图3-1所示。
图 31 添加callmethodaction
确保callmethodaction处于选中状态,在properties面板上triggertype右边的new按钮,如图3-2所示。
图 32 单击new按钮
在弹出的select object对话框里选择appbaritemtrigger,如图3-3所示,然后单击ok按钮关闭对话框。
图 33 选择appbaritemtrigger
此时,trigger的相关属性将会换成appbaritemtrigger的,把id属性的值设为sync,如图3-4所示。
图 34 appbaritemtrigger的属性
至于callmethodaction本身的属性,我们只需把targetobject属性绑到指定对象,然后把methodname属性的值设为指定方法的名字就行了。
页面导航行为
有了appbaritemtrigger,我们就可以使用expression blend sdk的navigatetopageaction为application bar实现打开页面的操作了,当然,更简单的办法是直接使用appbaritemnavigation,它的用法和appbaritemcommand类似,只是command属性换成了targetpage属性。
如果你希望在uri里包含查询字符串,而参数的值又是绑到视图模型的属性的,那么,你可以试试navigatewithquerystringaction。
打开assets窗口,选择behaviors类别,然后从右边把navigatewithquerystringaction拖到objects and timeline面板的[phoneapplicationpage]上,如图4-1所示。
图 41 添加navigatewithquerystringaction
确保navigatewithquerystringaction处于选中状态,在properties面板上trigger改为appbaritemtrigger,然后把id、type和targetpage三个属性的值分别改为statistic、menuitem和/statisticpage.xaml,如图4-2所示。
图 42 设置相关属性
假设我们希望包含的查询字符串是"hitcount=xx&timecount=yy",其中,xx和yy分别来自视图模型的hitcount和timecount两个属性,那么,我们可以通过navigatewithquerystringaction的parameters属性进行设置。
在properties面板上单击parameters属性右边的edit items in this collection按钮,在弹出的parameter collection editor对话框里单击add another item按钮添加一个参数,把field属性的值设为hitcount,把value属性绑到视图模型的hitcount属性,如图4-3所示。
图 43 添加参数
用同样的办法添加一个timecount参数,并把它的value属性绑到视图模型的timecount属性。
根据上述设置,navigatewithquerystringaction将会为我们创建一个这样的uri:/statisticpage.xaml?hitcount=9&timecount=13(假设用户单击statistic菜单项时,hitcount和timecount两个属性的值分别为9和13)。
由于navigatewithquerystringaction是一个triggeraction,这意味着它的用途并不限于application bar,你可以通过expression blend sdk的eventtrigger把它用到silverlight的button控件(或者其它控件)上。
最后,如果你需要的只是一个简单的后退,你可以使用gobackaction。和navigatewithquerystringaction一样,你可以通过appbaritemtrigger把它用到application bar上,也可以通过eventtrigger把它用到silverlight的button控件(或者其它控件)上。
绑定启用状态和显示文字
有些时候,你可能希望application bar上的按钮和菜单项可以根据某些条件自动调整启用状态,比如说,当页面的listbox控件里有内容时,sync按钮才可用,否则,它应该处于禁用状态。
appbaritemtrigger提供了一个isenabled依赖属性,当我们把它绑到视图模型的某个bool类型的属性时,前者会监听后者的更改,然后把修改后的值反映到application bar上的按钮或者菜单项的isenabled属性。
如果你使用的是appbaritemcommand,你可以通过icommand.canexecute方法的返回值指定启用/禁用状态,并在状态发生更改的时候触发canexecutechanged事件,剩下的事情appbaritemcommand会帮你处理好的。
至于application bar上的按钮和菜单项的显示文字,你也可能希望实现绑定,这种需求通常出现在多语言支持的应用里,这个时候,你可以把appbaritemtrigger的text依赖属性绑到资源对象的某个属性,前者会监听后者的更改,然后把修改后的值反映到application bar上的按钮或者菜单项的text属性。如果你使用的是appbaritemcommand或者appbaritemnavigation,你也可以通过它们的text依赖属性实现同样的效果。
看到这里,有些同学可能会担心id和text两个属性打起架来,放心吧,它们不会的。虽然它们最终都是关联到application bar上的按钮或者菜单项的text属性,但它们发生作用的时间是不同的。id属性只在行为初始化的时候用来查找application bar上的按钮或者菜单项,一旦找到,id属性就会功成身退了,从此刻开始,text属性将会派上用场,它会密切关注绑定源,并把更新反映到application bar上的按钮或者菜单项的text属性。
下课了……
<script></script>