【全面解禁!真正的Expression Blend实战开发技巧】第五章 从最常用ButtonStyle开始 - ImageButton
本章围绕ImageButton深入讨论,为什么是ImageButton? 图片本身就是表达美的最佳手段之一,自古形容美女,都说美的像画一样。而在实际项目中,ImageButton出现率非常高,而且未来一定会更高。不信,一起请看下图:(本程序源码http://www.kaodigua.net/download/Lession5.rar)
这两款软件相信大家都不陌生,一款是pplive,另一个是时下最火的iphone,在这两款软件中都典型的应用了ImageButton。除了图片,我们注意到上图中的ImageButton都还配有描述文字。假设你遇到类似的需求,你可能马上会意识到,Button的逻辑树中只有一个Content属性,要么放图片进去,要么输入文字。如果两者都要呢?我来列举一下可能实现的方法,当然他们都是负面教材,都是低效,不灵活或高成本的。(如果不幸您被我言中,使用了下面的方法,请宽恕我吧,我会用最佳解决方案作为补偿)
不推荐的做法:
1)、把图片和文字做成一张图片就解决啦!美工不就是干体力活的么,他们都不怕辛苦。
2)、我的按钮就是一个简单的TextButton,图片其实是LayoutRoot背景的一部分,这样他们看起来像是一起的就可以。不过整个程序的分辨率我必须写死,不然分辨率一改,我还要计算相对位置。
3)、我用Grid把Image和TextBlock都包裹好,然后作为Button的Content。不过如果想要针对图片做运动动画,而文字做改变颜色的动画,就不好办了。
4)、1楼,我就是那个不怕辛苦的美工,我不怕麻烦,我为每个Button都建一个专属样式,style1,style2,style3....。Button再多我也不怕,但你起码要告诉我,一共需要做多少个Button。
5)、我是程序员,我会自定义一个类,继承自Button,然后定义自己的依赖属性,命名为ImageUrl,然后在Button的Style中放一个Image,把Image的Source绑定到ImageUrl上。由于Source是一个地址字符串,我还需要书写代码,根据相对或者绝对地址读取图片。当然这样我要为每一个使用ImageButton的项目都自定一个Class,为了可以重用,尽量减少冗余,我把它封装为Class library,留着以后复用,但当我在第一个项目中引用我的library时,我发现我的ImageUrl属性无法找到地址中的图片?这该死的微软,在一个程序里好用,跨dll就不好用啦。我要骂微软,我要发帖子求解.....
6)、我比5号哪个程序员更会做脑筋急转弯,我把ImageContent变成TextContent, 传文本,跨100次dll也不会出错。
上述6种做法,都存在的各种明显的缺点,比如不灵活,冗余的代码,冗余的类,复杂的开发方式,过高的维护成本,较慢的开发速度。而最佳的做法一定集多种优点为一身,灵活,图片文本可以分开做不同的animation。简单,教一次就会做。快速,1分钟内就能搞定。最低的维护成本.最好以后都不用维护。当然未必完美,可在大多数情况下足够用了。还有一点,就是最佳的做法往往非常好理解,一点就通。不信你往下看,看完你也会说"啊,这么回事啊。知道了”。 好了好了不买官司了,下面开始最佳做法。
最佳的做法:
首先添加一个TextBlock到LayoutRoot。右击TextBlock,在弹出菜单中选择Make Into Control,将Style命名为ImageButtonStyle,然后可以得到下图中的效果。(如果你是新手,对于此步骤感到迷惑,可以在本系列的第三章找到此步骤的图文讲解)Blend为我们自动生成的样式元素结构下图所示,一个简单的ContentPresenter被Grid包裹。
点击下图中,最左侧的图标,Return Scope to[UserControl],切换到UserControl编辑视图。
此时我们需要几张图片作为素材,随便下载一些ICON就可以了,在项目中新建文件夹,名为Images,将图片拷贝进来,随便选择一张图片,将它拖拽到Button上,然后松开鼠标,得到下图中的效果。Image被Button包裹。
右击Button,在弹出菜单中选择 Edit Template -> Edit Current,切换到Style编辑视图。
下面是关键步骤:在ImageButtonStyle的Grid中,添加一个TextBlock,然后在右侧属性面板中找到TextBlock的Text属性,点击Text属性最右侧的小方块。在弹出菜单中选择TemplateBinding-> Tag。
再一次点击下图中,最左侧的图标,Return Scope to[UserControl],切换到UserControl编辑视图。
在Objects and Timeline面板中选择Button,然后查看右侧属性面板,找到Tag属性,输入一些文本比如“木头防火墙”
然后你会发现,奇迹出现了!嗯,稍作调整后,加一些你喜欢的动画等等。就变成下面的效果。
代码如下:
<Button Style="{StaticResource ImageButtonStyle}" Tag="木头防火墙" HorizontalAlignment="Left" Height="86" Margin="8,8,0,0" VerticalAlignment="Top" Width="64">
<Image Height="64" Source="Images/sytb_298.png" Stretch="Fill" Width="64"/>
</Button>
<Button Style="{StaticResource ImageButtonStyle}" Tag="调色板" Width="64" HorizontalAlignment="Left" Height="86" Margin="72,8,0,0" VerticalAlignment="Top">
<Image Height="64" Margin="0" Source="Images/sytb_087.png" Stretch="Fill" Width="64"/>
</Button>
<Button Style="{StaticResource ImageButtonStyle}" Tag="麦克风" Width="64" HorizontalAlignment="Left" Height="86" Margin="136,8,0,0" VerticalAlignment="Top">
<Image Height="64" Source="Images/sytb_099.png" Stretch="Fill"/>
</Button>
<Button Style="{StaticResource ImageButtonStyle}" Tag="我的电脑" Width="64" HorizontalAlignment="Left" Height="86" Margin="200,8,0,0" VerticalAlignment="Top">
<Image Height="64" Source="Images/sytb_116.png" Stretch="Fill"/>
</Button>
<Button Style="{StaticResource ImageButtonStyle}" Tag="安全退出" Height="86" Margin="264,8,312,0" VerticalAlignment="Top" Width="64">
<Image Height="64" Source="Images/sytb_081.png" Stretch="Fill"/>
</Button>
恭喜你,到这里你已经学会了ImageButton的最佳实战做法。
背后的原理
这种法只是利用了Button的Tag属性,翻看帮助文档,Tag是Object类型,几乎所有的控件都具有这个Tag属性,当然Button也不会例外。silverlight和wpf中都内置了专为xaml使用的简单类型转换器,比如在Source属性输入一个地址字符转,就可以看到图片,就是类型转换器的功劳。所以当我们在Tag属性中输入任何文字,也都会被转换器合理的转换。虽然微软silverlight开发团队不建议这样使用Tag属性,但他们也没告诉我应该用Tag做什么。而在我经历的N个实际项目中证明了,这种用法非常方便,没有任何副作用。所以,大家就放心的用吧。大多数情况下足够用了。
过几天工作会比较忙。博客更新较慢,请大家耐心。这几篇文章实在是我个人的诚意之作,如果大家觉得我的文章写的实用,好懂,就请帮我点一下推荐,让更多的人看到。也希望大家继续支持我。后面我与大家分享更多实战经验。