原文:【全面解禁!真正的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个实际项目中证明了,这种用法非常方便,没有任何副作用。所以,大家就放心的用吧。大多数情况下足够用了。

  过几天工作会比较忙。博客更新较慢,请大家耐心。这几篇文章实在是我个人的诚意之作,如果大家觉得我的文章写的实用,好懂,就请帮我点一下推荐,让更多的人看到。也希望大家继续支持我。后面我与大家分享更多实战经验。

【全面解禁!真正的Expression Blend实战开发技巧】第五章 从最常用ButtonStyle开始 - ImageButton的更多相关文章

  1. 【全面解禁!真正的Expression Blend实战开发技巧】十一章 全面解析布局(Grid & Canvas &StackPanel &Wrappanel)

    原文:[全面解禁!真正的Expression Blend实战开发技巧]十一章 全面解析布局(Grid & Canvas &StackPanel &Wrappanel) 写这篇文 ...

  2. 【全面解禁!真正的Expression Blend实战开发技巧】第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条 这一章讲解FluidMoveBehavior的另一个应用, ...

  3. 【全面解禁!真正的Expression Blend实战开发技巧】第二章 你好,UI设计师

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第二章 你好,UI设计师 你好,UI设计师 曾几何时我从没想过要与艺术家打交道,但是Silverlight改变了这一切.UI设计师 ...

  4. 【全面解禁!真正的Expression Blend实战开发技巧】第一章 真正的开发中的最佳的做法

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第一章 真正的开发中的最佳的做法 从设计者到开发者 设计师创建一个应用程序的布局然后让开发者去实现. 从开发者到设计者 开发者创建 ...

  5. 【全面解禁!真正的Expression Blend实战开发技巧】序章

    原文:[全面解禁!真正的Expression Blend实战开发技巧]序章 从silverlight2开始我也和大家一样一直在跟随微软的脚步,从sl2~sl4一步一步过来,总结了不少心得体会.由于各种 ...

  6. 【全面解禁!真正的Expression Blend实战开发技巧】第十章 FluidMoveBehavior完全解析之三飞出ListBox吧

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第十章 FluidMoveBehavior完全解析之三飞出ListBox吧 刚才有人说我的标题很给力,哈哈.那这个标题肯定更给力了 ...

  7. 【全面解禁!真正的Expression Blend实战开发技巧】第七章 MVVM初体验-在DataGrid行末添加按钮

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第七章 MVVM初体验-在DataGrid行末添加按钮 博客更新较慢,先向各位读者说声抱歉.这一节讲解的依然是开发中经常遇到的一种 ...

  8. 【全面解禁!真正的Expression Blend实战开发技巧】第八章 FluidMoveBehavior完全解析之一漂浮移动

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第八章 FluidMoveBehavior完全解析之一漂浮移动 好久没更新博客了,今天如果没急事,准备连发三篇,完全讲解Blend ...

  9. 【全面解禁!真正的Expression Blend实战开发技巧】第四章 从最常用ButtonStyle开始 - PathButton

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第四章 从最常用ButtonStyle开始 - PathButton 上一篇我们介绍了TextButton,但为了追求界面的张力, ...

随机推荐

  1. 【42.86%】【codeforces 742D】Arpa's weak amphitheater and Mehrdad's valuable Hoses

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  2. [Grid Layout] Use auto-fill and auto-fit if the number of repeated grid tracks is not to be def

    What about the situation in which we aren’t specifying the number of columns or rows to be repeated? ...

  3. thinkphp5多级控制器是什么?怎么使用?

    thinkphp5多级控制器是什么?怎么使用? 一.总结 1.多级控制器是让控制器的级数变成多级,也就是controller目录下可以新建其它目录. 2.使用的话注意目录下的控制的的命名空间(加上目录 ...

  4. php标准库中的优先队列SplPriorityQueue怎么使用?(继承)

    php标准库中的优先队列SplPriorityQueue怎么使用?(继承) 一.总结 1.new对象,然后通过insert方法和extract方法来使用,top方法也很常用. 2.类的话首先想到继承, ...

  5. 排序算法 基于Javascript

    写在前面 个人感觉:javascript对类似排序查找这样的功能已经有了很好的封装,以致于当我们想对数组排序的时候只需要调用arr.sort()方法,而查找数组元素也只需要调用indexOf()方法或 ...

  6. Opencv Surf算子中keyPoints,描述子Mat矩阵,配对向量DMatch里都包含了哪些好玩的东东?

    Surf算法是一把牛刀,我们可以很轻易的从网上或各种Opencv教程里找到Surf的用例,把例程中的代码或贴或敲过来,满心期待的按下F5,当屏幕终于被满屏花花绿绿的小圆点或者N多道连接线条霸占时,内心 ...

  7. .netcore consul实现服务注册与发现-单节点部署

    原文:.netcore consul实现服务注册与发现-单节点部署 一.Consul的基础介绍     Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分 ...

  8. color2gray 的实现

    无论是 rgb 还是 yuv 等三通道的颜色空间中的像素点,将其转换为单通道(pixel_depth=255.)中的像素,一般情况下都是采用的对原始颜色空间的 3 通道的像素点线性组合而得到单通道的像 ...

  9. 小强的HTML5移动开发之路(31)—— JavaScript回顾6

    HTML DOM模型: w3c dom 模型(规范)出现之前,各个浏览器自己支持的一些dom操作 Select对象 属性: selectedIndex:表示用户现在选择的那个选项的下标(从0开始) l ...

  10. 混合使用C++语言和Objective-C语言

    如果你的源文件扩展名是.m的,你还需要改成.mm,这样编译器才知道你将会在该文件中混合使用C++语言和Objective-C语言.