类似发送邮件android 改变控件位置内容样式的控件

全球最新的免费资源发布区
WordPress评论回复邮件通知附最新Windows主机回复评论发送邮件
& 日 22:26 &
WordPress评论回复邮件通知就是当别人回复了你在某一个Wordpress博客上的评论后,自动发送一封邮件到你的邮箱当中,并告诉你大概的评论内容和链接,以便你跟踪评论。
以前用的是国外的Linux虚拟空间,采用Wordpress架构,什么伪静态、回复邮件通知等功能都完全正常,怪不得别人说Linux是Wordpress运行的最好平台。
后来因为种种原因,将博客放在了国内。众所周知,国外的空间以Linux主机居多,而国内的各大主机商,基本上以Windows主机居多,我现在用的主机就是Windows主机。
换了空间后,麻烦就来了,首先是伪静态无法实现,后来花了我大量的时间和精力才搞定它。另一个致命的弱点就是运行在Windows主机上的Wordpress无法正常发送回复邮件通知。
其间也尝试过多种方法来实现Wordpress评论回复邮件通知,但是都是以失败而告终。没有回复评论邮件通知功能,不少人在QQ上向我反映这个问题,希望我可以加上这个功能。
恰好的免费资源部落的文章基本上也就是一些建站、空间使用类的文章,很多人是因为有问题才会留言,希望可以得到解答。所以,评论回复邮件通知功能实在非常重要。
不管你用的是Linux主机还是Windows主机,如果你发现你的Wordpress没有邮件发送和评论回复邮件通知功能,那么这篇文章将为你解决这个问题。特别是像我这样的Windows用户。
如果你对Wordpress美化和整合有兴趣,可以看看下面的:
1、(你可以为你的WP分类、标签或者特定的类别来打造上一篇、下一篇功能)
2、(有兴趣做英文网站的朋友可以用这个插件实现自动博客)
3、(这个程序可以完美整合到WP中,弥补WP在解决问题和用户讨论方面的不足)
WordPress评论回复邮件通知附最新Windows主机回复评论发送邮件
一、运行在Linux主机上的Wordpress无法发送评论回复邮件
1、一般来国外的主机空间以Linux居然,而Wordpress正是Linux平台运行的程序,对WP支持是最好的了。所以只要你的Wordpress安装在Linux主机上,邮件发送就不应该有问题。
2、Linux主机禁用了mail函数,关闭了openssl模块。这种情况比较少见,但是也有。测试自己用的主机是否禁用Wordpress使用到的mail()函数,最简单的方法是找回密码。
3、如果如下提示,就表示禁用了。这时候请直接联系人的主机商,叫他们帮你开通。
4、你的主机虽然支持mail函数,但是配置的环境比较差,邮件虽然可以发出去,但是很慢,而且经常还无法发送。这种情况经常见于一些便宜主机上。解决的办法是升级配置或者换主机。
二、运行在Windows主机上的Wordpress无法发送评论回复邮件
1、为什么windows主机不能使用邮件回复呢,因为它禁用了mail()函数,这使得所有邮件回复插件都不能用了。但是一般Windows主机会允许SMTP发信。
2、所以如果你正在使用Windows主机运行Wordpress,默认的是无法发送任何邮件的。我们要采用插件法来解决这个问题。
3、在网上搜索了一下,不少人和我一样遇到这种问题,由于插件冲突还有设置问题,至今还有不少人至今没有成功解决这个Win主机发邮件的问题
三、我的成功解决办法:Windows主机无法发送回复评论邮件
1、我要实现的效果是,当Wordpress有评论时自动发送一封邮件通知我。任何人回复任何人的评论都要发送一封通知邮件给被回复者的邮箱。不管是前台还是后台回复,都是成功发送评论回复邮件通知。
2、实现的方法:我目前用的插件是WP Thread Comment(嵌套回复插件),该插件已经有了回复邮件通知功能,但是因为Windows主机的原因,无法成功发送邮件。所以我需要用代码或者插件的方法启用这个功能。
3、成功的过程:经过无数次测试,最终我用Configure SMTP插件实现评论通知功能和回复评论邮件通知功能,但是有一个问题,就是前台回复评论可以成功发送邮件,而管理员后台回复评论则无法收到邮件。
4、最后我用到了另外一个插件Comment Reply Notification成功解决了后台回复评论发送邮件通知的问题。本以为同时启用两个评论回复邮件通知插件,在前台回复会出现两个邮件通知,但是经过我的测试后居然只收到一个。
5、也就是说Comment Reply Notification只支持后台回复评论邮件通知,前台回复则没有。当然也不一定是插件的问题,有可能是两个插件同时启用的问题。
四、最新Windows主机回复评论发送邮件通知
1、解决这个问题的前提是:你的Wordpress已经有了回复评论发送邮件通知的功能,只不过因为是Windows禁用mail函数的问题,导致无法正常发送邮件。
2、一般地你安装了WP Thread Comment就有了回复评论邮件通知功能,在插件后台启用即可,当然还有其他的插件或者手动添加代码的方法,可以自己谷歌一下。
3、首先安装Configure SMTP插件,这里是,还有官方网站:http://wordpress.org/extend/plugins/configure-smtp/
4、Configure SMTP插件设置。我使用QQ邮箱配置的,当然,你也可以使用其他例如163、Gmail等支持SMTP的邮箱来配置此插件。如下图(图片是缩略图,点击还原放大):
PS:日更新,由于发现普通的邮箱在SMTP发信中出现不少的问题,部落改用了企业邮箱:。
5、另外还要注意了,你使用的邮箱一定要开启IMAP/SMTP服务,像163邮箱好像没有开启,推荐你使用Gmail邮箱和QQ邮箱。QQ邮箱一般在账户设置中开启。如下图(图片是缩略图,点击还原放大):
6、设置完成后,点击保存。然后再发送一封测试邮件,如果提示发送成功,就表示你配置成功了。否则请对照上方检查错误。如下图:
7、Configure SMTP这个插件安装好后,然后在后台启用了WP Thread Comment的回复评论邮件通知功能。
8、经过我的测试,在前台(就是文章页面)回复评论被回复者的邮箱会收到邮件通知,但是管理员从后台管理面板回复评论则不会发送邮件。
9、解决上面的问题,又要用到另外一个插件Comment Reply Notification,这个插件可以很好解决后台管理回复评论邮件通知的问题。
10、这里是,还有官方网站:http://wordpress.org/extend/plugins/comment-reply-notification/
11、记得在插件后台设置成回复发送邮件。如下图:
12、另外Comment Reply Notification发送邮件默认是英文的,你可以自己修改成中文的。下面给出我的邮件原文代码,你可以直接复制过去。
&p&&/p&&p&&strong&[pc_author]: &/strong&&/p&&p&&strong&您好&/strong&,您之前在文章《[postname]》上的评论现在有了新的回复&/p&&p&您之前的评论是([pc_date] ):&br /&[pc_content]&/p&&p&&strong&[[cc_author]]&/strong&回复您如下([cc_date]):&br /&[cc_content]&/p&&p&请点击以下链接查看具体内容:&br /&&a href="[commentlink]"&[commentlink]&/a&&/p&&br /&&strong&感谢您对 &a href="[blogurl]"&[blogname]&/a& 的关注&/strong&&br /&&strong&该信件由系统自动发出, 请勿回复, 谢谢.&/strong&&/p&&p&&strong&如果你有任何疑问,请联系我。邮箱:,我的QQ:&/strong&&/p&
五、Wordpress回复评论邮件通知测试效果
1、因为我设置了任意回复邮件通知,所以基本上只要有回复,就会有邮件通知。如下:
2、因为用的是QQ邮箱的SMTP,所以可以在QQ邮箱的已发送中看到已经送过的邮件,如下:
3、回复评论邮件发送有时快,有时慢,而且还有两个问题,一个是如果在后台首页点击回复,是不会发送邮件通知的。
4、另一个问题是利用WP Thread Comment的后台嵌套回复评论功能回复也是无法发送邮件通知的。如下图:
5、具体有效果你可以直接在文章下面留言等有回复时你即可收到邮件。有任何Bug欢迎告诉我。
六、回复评论发送邮件小结
1、本篇文章主要是解决Wordpress的mail()函数无法正常发送邮件从而改用SMTP发送邮件通知的问题。
2、但是如果你测试依然没有成功,那么很有可能你的主机连SMTP也给禁用了。这样的主机不用也罢了。
3、最近Wordpress3.3全新版已经出来了,是观望呢还是升级呢?升级失败又该怎么办?这些问题咱们分类的下一篇文章讨论。
文章出自:
版权所有。本站文章除注明出处外,皆为作者原创文章,可自由引用,但请注明来源。 禁止全文转载。
真的,我猜你也会喜欢的:
您或许对下面这些文章有兴趣:&&&&&&&&&&&&&&&&&&&&本月吐槽辛苦排行榜
免费资源部落博客、论坛、问答和优惠网的创建者
经常混迹于各种免费资源中,尝鲜后乐于分享给他人。用WP搭建了部落博客,没事儿就折腾Wordpress,喜欢找免费空间,但只求精,稳定,耐用。有时也会介绍一点关于建站的知识和主机、服务器的使用心得与体会。PS:此人为男。
TA的专栏:&&|&&
关于本文的作者
所属分类:
链接地址:
浏览前页:
浏览后页:
部落快速搜索栏
热门点击排行榜
网站导航栏
免费资源重点推荐
最新文章推荐
部落最新评论列表
不得不看的秘密
部落本月最受关注的热点
(热度269℃) (热度242℃) (热度152℃) (热度117℃) (热度96℃) (热度91℃) (热度87℃) (热度83℃) (热度77℃) (热度72℃) (热度71℃) (热度64℃) (热度64℃) (热度62℃) (热度54℃) (热度50℃) (热度48℃)
部落本月踩得最多的宝贝
(踩17,730次) (踩17,580次) (踩9,350次) (踩8,830次) (踩8,640次) (踩5,640次) (踩4,860次) (踩4,390次) (踩4,390次) (踩4,200次)
免费资源部落,是一个致力发布和推广来自世界各地的免费资源,包括多样实用的免费空间、各种优秀的免费软件、各样可用的免费网盘等个人博客网站。站长qi是一位很普通不过的人,长期关注网络空间、互联网、软件应用、程序开发与设计、网络应用等。免费资源部落成立的目的就是希望与更多人分享网络快乐与精彩!本站持续修改完善中,如遇不便还请谅解^_^查看: 26295|回复: 66
如何修改邮箱验证等自动发送邮件的样式的方法~~~~~~超赞,不看后悔............
不墨迹,直接上图...............
邮箱激活:
QQ截图06.png (14.11 KB, 下载次数: 4)
22:56 上传
密码找回:
QQ截图42.png (14.22 KB, 下载次数: 5)
22:56 上传
首先打开source/language/lang_email.php文件,所以系统自动发送文件都在这个文件夹内,直接将内容替换即可,
如要修改: 'birthday_subject' =& '祝您生日快乐',
'birthday_message' =& '
{username},
这封信是由 {bbname} 发送的。
您收到这封邮件,是由于这个邮箱地址在 {bbname} 被登记为用户邮箱,
并且按照您填写的信息,今天是您的生日。很高兴能在此时为您献上一份
生日祝福,我谨代表{bbname}管理团队,衷心祝福您生日快乐。
如果您并非 {bbname} 的会员,或今天并非您的生日,可能是有人误用了您的邮
件地址,或错误的填写了生日信息。本邮件不会多次重复发送,请忽略这封邮件。
{bbname} 管理团队.
{siteurl}',复制代码则直接将以下代码替换掉,最后的',单引号和逗号一定要保留: &STRONG&&FONT face=宋体&{username},
这封信是由 {bbname} 发送的。
您收到这封邮件,是由于这个邮箱地址在 {bbname} 被登记为用户邮箱,
并且按照您填写的信息,今天是您的生日。很高兴能在此时为您献上一份
生日祝福,我谨代表{bbname}管理团队,衷心祝福您生日快乐。
如果您并非 {bbname} 的会员,或今天并非您的生日,可能是有人误用了您的邮
件地址,或错误的填写了生日信息。本邮件不会多次重复发送,请忽略这封邮件。
{bbname} 管理团队.
{siteurl}&/FONT&&/STRONG&复制代码好了,下面发布我的这个模版出来: &STRONG&&DIV&
&DIV& &/DIV&
&DIV style=&COLOR: #000&&
&DIV align=center&
&TABLE style=&BORDER-BOTTOM: #d9e9f1 3 TEXT-ALIGN: BORDER-LEFT: #d9e9f1 3 BACKGROUND: #7 BORDER-TOP: #d9e9f1 3 BORDER-RIGHT: #d9e9f1 3px solid& cellSpacing=1 cellPadding=0&
&TBODY&
&TR&
&TD style=&PADDING-BOTTOM: 0 PADDING-LEFT: 0 PADDING-RIGHT: 0 PADDING-TOP: 0px&&
&TABLE style=&BORDER-BOTTOM: #ffffff 1 BORDER-LEFT: #ffffff 1 WIDTH: 500 BACKGROUND: #f7f7f7; BORDER-TOP: #ffffff 1 BORDER-RIGHT: #ffffff 1px solid& cellSpacing=0 cellPadding=30&
&TBODY&
&TR&
&TD style=&LINE-HEIGHT: 2; FONT-SIZE: 12px&&
&DIV style=&MARGIN-BOTTOM: 10 FONT-SIZE: 14 FONT-WEIGHT: 700&&Hi, &SPAN class=STYLE1&{username}&/SPAN&,这封信是{bbname}的密码找回邮件!&/DIV&
&P style=&MARGIN: 0 COLOR: #ff6600&&请点击下面的链接重置密码:&/P&
&DIV style=&BORDER-BOTTOM: #cbcbcb 1 BORDER-LEFT: #cbcbcb 1 PADDING-BOTTOM: 8 LINE-HEIGHT: 1.5; MARGIN: 10px 0px 5 PADDING-LEFT: 10 PADDING-RIGHT: 10 WORD-WRAP: break- BACKGROUND: # FONT-SIZE: 14 WORD-BREAK: break- BORDER-TOP: #cbcbcb 1 BORDER-RIGHT: #cbcbcb 1 PADDING-TOP: 8px&&&a href=&{siteurl}member.php?mod=getpasswd&uid={uid}&id={idstring}& target=&_blank&&{siteurl}member.php?mod=getpasswd&uid={uid}&id={idstring}&/a&&/DIV&
&DIV style=&MARGIN-BOTTOM: 5 COLOR: #999999&&如果不能点击链接,请复制地址并粘贴到浏览器的地址输入框&/DIV&
在上面的链接所打开的页面中输入新的密码后提交,您即可使用新的密码登录网站了。您可以在用户控制面板中随时修改您的密码。
&DIV style=&BACKGROUND: # HEIGHT: 1 OVERFLOW: BORDER-TOP: #e2e2e2 1px solid&&&/DIV&
&DIV style=&BACKGROUND: # HEIGHT: 1 OVERFLOW: BORDER-TOP: #e2e2e2 1px solid&&&/DIV&
社区地址:&FONT color=#3366cc& &A &&/A&
感谢您的访问,祝您使用愉快!如有疑问请联系管理员,邮箱:&/FONT&&/TD&
&/TR&&/TBODY&&/TABLE&&/TD&&/TR&&/TBODY&&/TABLE&&/DIV&&/DIV&&/DIV&
&DIV&&/DIV&
&DIV&&/DIV&&/STRONG&复制代码根据直接的需要修改......
下面是我修改好的懒人包,直接替换就可以......
(3.34 KB, 下载次数: 844)
23:03 上传
点击文件名下载附件
孔子曰:看帖不回没JJ也。
孟子曰:孔子说得对。
孔子曰:看帖从不回者,老婆一直是处女。
孟子曰:你丫又说对了!
<p id="rate_177" onmouseover="showTip(this)" tip="用上了并测试通过,感谢楼主提供!&金币 + 1 枚
" class="mtn mbn">
本帖被以下淘专辑推荐:
& |主题: 399, 订阅: 102
& |主题: 204, 订阅: 24
& |主题: 5, 订阅: 0
& |主题: 3, 订阅: 0
& |主题: 1, 订阅: 0
{:soso__:}
哈哈,经典!学习到啦!
这个确实不错!。
嗯,不错的hack
头像被屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
:lol:lol:lol:lol
湖南论坛顶起,已经用上,谢谢楼主。
自己顶下~
来自:Discuz! 官方站 Android客户端来自: Android客户端
顶起来。。&&
Powered byWPF之样式和控件模板 - 推酷
WPF之样式和控件模板
提到样式应该要追溯到 Html中的CSS样式了,通常是为了使多个元素(控件)达到一个效果(外观或者拥有相同的功能);当然,在WPF中也有类似于CSS这样,不过肯定是比CSS更要强大的哦。
&StackPanel&
&Button Height=&50& Margin=&0 10 0 0& Background=&Beige&
Width=&100&&
&Button.RenderTransform&
&RotateTransform Angle=&45&&&/RotateTransform&
&/Button.RenderTransform&
&Button Height=&50& Margin=&0 10 0 0& Background=&Beige&
Width=&100&&
&Button.RenderTransform&
&RotateTransform Angle=&45&&&/RotateTransform&
&/Button.RenderTransform&
&Button Height=&50& Margin=&0 10 0 0& Background=&Beige&
Width=&100&&
&Button.RenderTransform&
&RotateTransform Angle=&45&&&/RotateTransform&
&/Button.RenderTransform&
&/StackPanel&
上边的三个按钮使用了同样的倾斜规则,好在我们只有3个按钮,如果我们有几十个或者更多呢,实在是看着不舒服,也是对资源的极其浪费.如果我们提取出样式会是怎样的呢:
&UserControl.Resources&
&Style TargetType=&Button&&
&Setter Property=&Height& Value=&50&&&/Setter&
&Setter Property=&Width& Value=&100&&&/Setter&
&Setter Property=&Margin& Value=&0 10 0 0&&&/Setter&
&Setter Property=&Background& Value=&Beige&&&/Setter&
&Setter Property=&RenderTransform&&
&Setter.Value&
&RotateTransform Angle=&45&&&/RotateTransform&
&/Setter.Value&
&/UserControl.Resources&
添加了这样一个Style样式,切忌要放到Resource中哦(当前是Usercontrol,也可以是Grid或者其他元素的),使用如下:
&Grid x:Name=&LayoutRoot& Background=&White&&
&StackPanel&
&/StackPanel&
哈哈,是不是很奇怪呢,我对Button什么也没有做,看到的效果依然如此
为什么呢,当添加了Style之后,并且没有对Style设置Key,同时呢设置了TargetType,那么此TargetType的控件就会自动用上你给的样式哦.
样式的继承
上边的使用是最简单的样式使用方式,下面有一个新的需求,我们添加了一个RadioButton,同样也希望旋转45度,但是呢RadioButton也有自己不同的地方,这时候呢又想重用之前的样式代码,怎么办呢?还好我们有样式继承功能BaseOn属性,看看下边怎么做.
&Window.Resources&
&Style TargetType=&{x:Type Control}&&
&Setter Property=&Height& Value=&50&&&/Setter&
&Setter Property=&Width& Value=&100&&&/Setter&
&Setter Property=&Margin& Value=&0 10 0 0&&&/Setter&
&Setter Property=&Background& Value=&Beige&&&/Setter&
&Setter Property=&RenderTransform&&
&Setter.Value&
&RotateTransform Angle=&45&&&/RotateTransform&
&/Setter.Value&
&Style BasedOn=&{StaticResource {x:Type Control}}& TargetType=&RadioButton&&
&Setter Property=&Foreground& Value=&Blue&&&/Setter&
&Setter Property=&FontSize& Value=&50&&&/Setter&
&Style BasedOn=&{StaticResource {x:Type Control}}& TargetType=&Button&&
&Setter Property=&FontSize& Value=&22&&&/Setter&
&Setter Property=&Foreground& Value=&Red&&&/Setter&
&/Window.Resources&
&在上边中主要就是使用了BaseOn属性来设置一个看起来比较费解的值.第一个Style标签是我们样式的基类,基类没有名字,只指定了TargetType=&{x:Type Control}&,即样式应用到所有的控件;两个子样式都BaseOn了这个基样式,BaseOn=&{StaticResource {x:Type Control}}&,这个式子蛮奇怪,那是因为我们的基类样式没有指定Key,如果指定了,那么我们的写法就是 BaseOn=&{StaticResource baseStyleName}&,如果样式没有指定key,那么就认为是TargetType的值了。效果如下:
&StackPanel Orientation=&Horizontal& HorizontalAlignment=&Center&&
Content=&Test&&&/Button&
Content=&Test&&&/Button&
&RadioButton &男&/RadioButton&
&/StackPanel&
三个按钮都应用了样式,当然有公共的和自己的样式.
样式触发器
样式中还有一个很好玩的功能,就是Triggers集合,这个是专门的触发器集合.首先来看如何通过触发器实现按钮悬浮时候改变字体颜色的功能.
&Style BasedOn=&{StaticResource {x:Type Control}}& TargetType=&{x:Type Button}&&
&Setter Property=&FontSize& Value=&22&&&/Setter&
&Setter Property=&Foreground& Value=&Red&&&/Setter&
&Style.Triggers&
&Trigger Property=&IsPressed& Value=&true&&
&Setter Property = &Foreground& Value=&Green&/&
&/Trigger&
&/Style.Triggers&
WPF中有3种触发器:
1.属性触发器:即上例子;
2.数据触发器(DataTrigger):普通的.net属性或者是依赖属性改变时触发;
3.事件触发器(EventTrigger):触发路由事件时会被调用。
事件触发器:
&ListBox.Triggers&
&EventTrigger RoutedEvent=&ListBox.Loaded&&
&BeginStoryboard&
&Storyboard&
&DoubleAnimation Storyboard.TargetProperty=&Opacity& From=&0& To=&1& Duration=&0:0:5&&&/DoubleAnimation&
&/Storyboard&
&/BeginStoryboard&
&/EventTrigger&
&/ListBox.Triggers&
上边的代码制作了一个ListBox的动画效果,使ListBox的透明度从0变到1,通过EventTrigger来实现.EventTrigger的RoutedEvent属性表示发生的事件,上边代码表示ListBox的Loaded事件.与属性触发器不同,EventTrigger中是TriggerAction的集合,即发生的事件和执行的操作.BeginStroyboard是一种操作,用于开始动画效果.
数据触发器:
DataTrigger之所以能够支持普通.Net属性,是因为它比属性触发器多了一个属性Binding,通过绑定来指定相关属性。
public class Student
private int _
public int Age
get { return _ }
set { _age = }
private string _
public string Name
get { return _ }
set { _name = }
一个自定义的类,用于绑定ListBox.
List&Student& students = new List&Student& {
new Student{ Age=18, Name=&Listen&},
new Student{ Age=12, Name=&Fly&},
new Student{ Age=18, Name=&Colors&},
new Student{ Age=9, Name=&Blue&},
this.lstStudent.ItemsSource =
在后置代码中进行初始化List集合,并赋值给ListBox.
&Window.Resources&
&Style TargetType=&ListBoxItem&&
&Setter Property=&Margin& Value=&0 , 2, 0, 2&&&/Setter&
&Setter Property=&Padding& Value=&0 , 2, 0, 2&&&/Setter&
&Setter Property=&FontFamily& Value=&微软雅黑&&&/Setter&
&Style.Triggers&
&DataTrigger Binding=&{Binding Path=Age}& Value=&18&&
&Setter Property=&Background& Value=&LightBlue&&&/Setter&
&/DataTrigger&
&/Style.Triggers&
&/Window.Resources&
添加针对ListBoxItem的样式,其中的DataTrigger为数据触发器,Bindding就是绑定的属性,当Age的值为18的时候,就设置ListBoxItem的背景色为LightBlue。
&ListBox x:Name=&lstStudent& DisplayMemberPath=&Name&&
&/ListBox&
第一行和第三行的Age为18,背景色也发生了变化.
模板完整示例:
&Grid.Resources&
&ControlTemplate x:Key=&buttonTemplate&&
&Grid Width=&100& Height=&100&&
&Ellipse x:Name=&outerCircle& Width=&100& Height=&100&&
&Ellipse.Fill&
&LinearGradientBrush StartPoint=&0,0& EndPoint=&0,1&&
&GradientStop Offset=&0& Color=&Blue&/&
&GradientStop Offset=&1& Color=&Red&/&
&/LinearGradientBrush&
&/Ellipse.Fill&
&/Ellipse&
&Ellipse Width=&80& Height=&80&&
&Ellipse.Fill&
&LinearGradientBrush StartPoint=&0,0& EndPoint=&0,1&&
&GradientStop Offset=&0& Color=&White&/&
&GradientStop Offset=&1& Color=&Transparent&/&
&/LinearGradientBrush&
&/Ellipse.Fill&
&/Ellipse&
&ControlTemplate.Triggers&
&Trigger Property=&Button.IsMouseOver& Value=&True&&
&Setter TargetName=&outerCircle& Property=&Fill& Value=&Orange&/&
&/Trigger&
&Trigger Property=&Button.IsPressed& Value=&True&&
&Setter Property=&RenderTransform&&
&Setter.Value&
&ScaleTransform ScaleX=&0.9& ScaleY=&0.9&/&
&/Setter.Value&
&Setter Property =&RenderTransformOrigin& Value=&.5,.5&/&
&/Trigger&
&/ControlTemplate.Triggers&
&/ControlTemplate&
&/Grid.Resources&
此模板实现了,嵌套了两个Ellipse,最主要的是悬浮到按钮上,外层Ellipse的颜色会变为Orange,点击按钮则会缩放按钮的大小为90%.
模板工作原理:
WPF中的模板分别为ControlTemplate(控件模板)、DataTemplate(数据模板)、HierarchicalDataTemplate(
表示支持&HeaderedItemsControl(表示包含多个项目并具有标头的控件)的&DataTemplate&,例如&TreeViewItem&或&MenuItem
)和ItemsPanelTemplate(项容器模板,例如ListBox的Items的容器模板),它们均继承自FrameworkTemplate,其中HierarchicalDataTemplate继承自DataTemplate。
&模板通过改变控件的可视化树(visual Tree)来彻底改变其外观,比如上边代码将按钮的可视化树变为两个嵌套的Ellipse。&控件均派生自Control的类,只有Control及其派生类才有Template 这样的属性
模板绑定和模板触发器:
&Grid.Resources&
&ControlTemplate x:Key=&buttonTemplate& TargetType=&{x:Type Button}&&
&Ellipse x:Name=&outerCircle&&
&Ellipse.Fill&
&LinearGradientBrush StartPoint=&0,0& EndPoint=&0,1&&
&GradientStop Offset=&0& Color=&{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background.Color}&/&
&GradientStop Offset=&1& Color=&Red&/&
&/LinearGradientBrush&
&/Ellipse.Fill&
&/Ellipse&
&Ellipse RenderTransformOrigin=&.5,.5&&
&Ellipse.RenderTransform&
&ScaleTransform ScaleX=&.8& ScaleY=&.8&/&
&/Ellipse.RenderTransform&
&Ellipse.Fill&
&LinearGradientBrush StartPoint=&0,0& EndPoint=&0,1&&
&GradientStop Offset=&0& Color=&White&/&
&GradientStop Offset=&1& Color=&Transparent&/&
&/LinearGradientBrush&
&/Ellipse.Fill&
&/Ellipse&
&ContentPresenter Margin=&20& Content=&{TemplateBinding Content}&/&
&/Viewbox&
&ControlTemplate.Triggers&
&Trigger Property=&Button.IsMouseOver& Value=&True&&
&Setter TargetName=&outerCircle& Property=&Fill& Value=&{Binding RelativeSource={RelativeSource TemplatedParent},Path=BorderBrush}&/&
&/Trigger&
&Trigger Property=&Button.IsPressed& Value=&True&&
&Setter Property=&RenderTransform&&
&Setter.Value&
&ScaleTransform ScaleX=&0.9& ScaleY=&0.9&/&
&/Setter.Value&
&Setter Property =&RenderTransformOrigin& Value=&.5,.5&/&
&/Trigger&
&Trigger Property=&IsEnabled& Value=&False&&
&Setter TargetName=&outerCircle& Property=&Fill& Value=&Gray&&
&/Trigger&
&/ControlTemplate.Triggers&
&/ControlTemplate&
&/Grid.Resources&
&StackPanel&
&Button Width=&100& Height=&100& Template=&{StaticResource buttonTemplate}& Click=&Button_Click& Content=&OK& Background=&CadetBlue& BorderBrush=&BurlyWood&
&TextBlock Text=&IsEnable = True& HorizontalAlignment=&Center&/&
&Button Width=&100& Height=&100& Template=&{StaticResource buttonTemplate}& Click=&Button_Click& Content=&Disabled& IsEnabled=&False&&&/Button&
&TextBlock Text=&IsEnable = False& HorizontalAlignment=&Center&/&
&/StackPanel&
重新修改了之前的示例代码,主要是修改了Ellipse的颜色,使用了LinearGradientBrush线性画刷,同时使用了RelativeResource相对资源绑定方式,此处的TemplatedParent应为Button本身,使用ContentPresenter来绑定按钮的Content,切记是使用TemplateBinding来绑定&。
模板绑定(TemplateBinding)类似一般的数据绑定,与一般的绑定相比有如下限制:
1.仅在模板的可视化树内部有效,在模板外部,甚至模板的Trigger中都无效。
2.不能应用在
派生对象的属性上,如果你尝试绑定Brush的Color属性,则会失败哦。
我们上述代码有两处的数据绑定,一个是Ellipse的Fill属性中。因为Color属于Freezable派生的对象的属性,因此不能使用模板绑定。二是在Trigger中对IsMouseOver的处理,这事因为Trigger不属于控件模板的可视化树内容,因此使用模板无效。
模板和样式触发器比较类似,但是有区别哦:
1.样式触发器无法应用于模板的某个元素,而模板的触发器可以。比如上例子中可以在IsMouseOver为true的时候设置第一个Ellipse的Fill属性,而在样式中只能设置整个控件的某个属性。Setter的TargeName和Trigger的SourceName属性均用来指定模板中的某个子元素,该子元素必须有一个名字。
2.样式触发器优先级高于模板的触发器。
接下来和大家分享一个小程序,控件模板的浏览器程序(来自WPF葵花宝典一书):
&Grid.RowDefinitions&
&RowDefinition Height=&*&/&
&RowDefinition Height=&20&/&
&/Grid.RowDefinitions&
&Grid Grid.Row=&0& Name=&grid& &
&Grid.ColumnDefinitions&
&ColumnDefinition Width=&*&&&/ColumnDefinition&
&ColumnDefinition Width=&2&&&/ColumnDefinition&
&ColumnDefinition Width=&3*&&&/ColumnDefinition&
&/Grid.ColumnDefinitions&
&GridSplitter Grid.Column=&1& ResizeDirection=&Columns& VerticalAlignment=&Stretch& Width=&2& Background=&Black& HorizontalAlignment=&Center& ShowsPreview=&True&/&
&TreeView DisplayMemberPath=&Name& Name=&lstTypes& SelectedItemChanged=&lstTypes_SelectedItemChanged&&&/TreeView&
&TextBox Grid.Column=&2& Name=&txtTemplate& TextWrapping=&Wrap& VerticalScrollBarVisibility=&Visible& FontFamily=&Consolas&&&/TextBox&
&TextBlock x:Name=&txtbar& Grid.Row=&1& Height=&18& HorizontalAlignment=&Left& Margin=&10,0,0,0&
Text=&Wait&&&/TextBlock&
后置代码如下:
private void Window_Loaded(object sender, RoutedEventArgs e)
// 获得Control的程序集
Assembly asbly = Assembly.GetAssembly(typeof(Control));
// 获得该程序集里的所有类型
Type[] atype = asbly.GetTypes();
// 使用该列表存储
SortedList&string, TreeViewItem& sortlst =
new SortedList&string, TreeViewItem&();
TreeViewItem item = new TreeViewItem();
item.Header = &Control&;
item.Tag = typeof(Control);
sortlst.Add(&Control&, item);
lstTypes.Items.Add(item);
// 遍历所有的类型,然后将派生自contorl的类型添加到列表当中
foreach (Type typ in atype)
if (typ.IsPublic && (typ.IsSubclassOf(typeof(Control))))
item = new TreeViewItem();
item.Header = typ.N
item.Tag =
sortlst.Add(typ.Name, item);
foreach (KeyValuePair&string, TreeViewItem& kvp in sortlst)
if (kvp.Key != &Control&)
string strParent = ((Type)kvp.Value.Tag).BaseType.N
TreeViewItem itemParent = sortlst[strParent];
itemParent.Items.Add(kvp.Value);
private void lstTypes_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs&object& e)
Cursor oldcur = this.C
this.Cursor = Cursors.W
// 获得选中的类型
TreeViewItem selectedItem = (TreeViewItem)lstTypes.SelectedI
if (selectedItem.HasItems)
this.Cursor =
//wndBar.Hide();
Type type = (Type)selectedItem.T
// 实例化该type
ConstructorInfo info = type.GetConstructor(System.Type.EmptyTypes);
Control control = (Control)info.Invoke(null);
// 添加该控件 但是将属性状态设置为Collapsed.
control.Visibility = Visibility.C
grid.Children.Add(control);
// 获得模板
ControlTemplate template = control.T
// 获得模板的XAML文件
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb, settings);
XamlWriter.Save(template, writer);
// 显示模板
txtTemplate.Text = sb.ToString();
txtbar.Text = type.Name + &Control Template&;
// 移出该控件
grid.Children.Remove(control);
this.Cursor =
catch (Exception err)
txtTemplate.Text = &&& Error generating template: & + err.Message + &&&&;
效果图如下:
样式和主题:
其实WPF中的主题或者是换肤其实就是通过样式和模板来实现的,当然通常会建立一个个xaml资源字典存放不同风格的样式,一般是在App.xaml中引入需要的样式字典。如下代码:
&Application.Resources&
&ResourceDictionary&
&ResourceDictionary.MergedDictionaries&
&ResourceDictionary Source=&Resources/button.xaml&&&/ResourceDictionary&
&/ResourceDictionary.MergedDictionaries&
&/ResourceDictionary&
&/Application.Resources&
&/Application&
窗体代码:
&Grid.RowDefinitions&
&RowDefinition Height=&Auto&/&
&RowDefinition Height=&*&/&
&/Grid.RowDefinitions&
&Menu Grid.Row=&0& VerticalAlignment=&Top&&
&MenuItem Header=&皮肤& &
&MenuItem Header=&简单按钮风格& Name=&simpleSkin& Click=&MenuItem_Click& IsChecked=&True&&&/MenuItem&
&MenuItem Header=&个性化按钮风格& Name=&fancySkin& Click=&MenuItem_Click&&&/MenuItem&
&/MenuItem&
&Button Grid.Row=&1& Content=&OK& VerticalAlignment=&Center& HorizontalAlignment=&Center&/&
后置代码:
private void MenuItem_Click(object sender, RoutedEventArgs e)
MenuItem menuItem = (MenuItem)
if(menuItem == null) return;
if (menuItem == simpleSkin)
ResourceDictionary newDictionary = new ResourceDictionary();
newDictionary.Source = new Uri(&Resources/button.xaml&, UriKind.Relative);
Application.Current.Resources.MergedDictionaries[0] = newD
menuItem.IsChecked = true;
fancySkin.IsChecked = false;
else if (menuItem == fancySkin)
ResourceDictionary newDictionary = new ResourceDictionary();
newDictionary.Source = new Uri(&Resources/fancyButton.xaml&, UriKind.Relative);
Application.Current.Resources.MergedDictionaries[0] = newD
menuItem.IsChecked = true;
simpleSkin.IsChecked = false;
主要是通过Application.Current.Resources.MergedDictionaries.Add添加一个ResourceDictionary或者是直接修Application.Current.Resources.MergedDictionaries[0] 的值即可,主要代码是,通过设置ResourceDictionary的Source来指定需要的资源文件;这样在切换选中的菜单项之后就可以看到按钮样式的不同哦。
希望大家多多交流讨论。
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见}

我要回帖

更多关于 android日期控件样式 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信