当前位置:编程学习 > wap >>

Windows Phone自定义主题

我们知道Windows Phone默认的主题系统是由黑白两色为背景和一些强调色组成的,用户可以随意切换。通常来说,应用开发者无需关心这一部分,系统会去更新相关的资源,然后再体现在应用中。
但有一些时候,我们基于品牌等因素的考量,可能不想使用Windows Phone的默认主题。比如我开发的“豆芽”是豆瓣网的一个客户端,我希望尽可能贴近豆瓣网本身清新的风格,而不是给用户呈现一个和豆瓣网风格大相径庭的黑色背景的界面;再比如我想让应用使用Windows Phone的默认字体(等线),而不是SDK的默认字体(雅黑)。
这些都需要我们去自定义应用的主题。
在介绍如何创建自定义主题之前,先来简单的描述一下Windows Phone主题的原理。
在Windows Phone中,系统预定义了许多资源,这些资源包括了画笔、颜色、字体、粗细、字号、文本样式等等最基本的元素(详细的资源名称可以查看这里http://msdn.microsoft.com/zh-cn/library/ff769552%28v=vs.92%29.aspx)。此外,Windows Phone中的所有控件都会有自己的样式,样式中还包括了定义控件布局的模板,而模板又利用系统内置的资源定义了控件在各种状态下的外观(所以我们在XAML中随处可以见类似{StaticResource PhoneBackgroundBrush}这样的对内置资源的引用)。


所以我们可以想到,修改内置资源或者修改控件的样式都可以达到自定义主题的效果。
在早期的Windows Phone v7.0),我们可以使用前一种方式,只需要在应用中增加一个ResourceDictionary的XAML文件,里边添加若干和系统资源相同键名的资源,即可实现对系统资源的覆盖。
但这种方法在Mango (v7.1)中无效了,它被当作一个Bug修复了,所以我们只能另寻方法。代价最小的一种方法是在App初始化的时候动态的读取我们定义的ResourceDictionary,并替换系统内置资源。具体的步骤可以参考这里http://windowsphonegeek.com/articles/Windows-Phone-Mango-Custom-application-Theme-Step-by-Step  ,我就不赘述了。
此外,还可以利用Mango带来的另外一个变化,新的Silverlight 4带来的“隐式样式”(Implicit Style)。隐式样式是指只有TargetType却没有指定Key的Style,在Silverlight 4中,会将这个Style应用到所有匹配的TargetType对象上。
我们可以利用“隐式样式”来更改内置控件的样式,只需要将需要修改的控件的样式添加到应用的ResourceDictionary中,将其Key值去掉即可(当然不去掉也可以,这就需要手工设置所有匹配控件的Style属性)。
但一般情况下,既然我们想要更改应用级别的主题,基本上我们会修改整套配色方案,如果单纯用“隐式样式”来实现的话,我们就需要实现所有控件的隐式样式,看起来似乎也不是一件简单的事情。
本文来介绍另外一种方法,这种方法不仅实现了所有控件的样式,还一并接管了所有的内置资源,但它的实现过程却一点儿也不复杂。
首先
我们在项目中添加一个XAML文件,用来存放新的主题,这里将文件名定为“CustomTheme.xaml”,下面是它的内容:
<ResourceDictionary
 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 
xmlns:System="clr-namespace:System;assembly=mscorlib">
 
</ResourceDictionary>

然后编辑App.xaml,添加相应的ResourceDictionary:
<Application.Resources>
 
<ResourceDictionary>
 
<ResourceDictionary.MergedDictionaries>
 
<ResourceDictionary Source="CustomTheme.xaml"/>
 
</ResourceDictionary.MergedDictionaries>
 
</ResourceDictionary>
 

接着打开Windows Phone SDK附带的设计资源文件夹:C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Design。我们会看到若干文件夹,这些文件夹都对应于Windows Phone中的一个主题搭配,譬如LightGreen表示浅色背景色和绿色强调色的搭配。

  \


 

挑选一个最贴近我们想要的主题配色的文件夹打开,我们会看到两个XAML文件,其中ThemeResources.xaml中定义了系统资源,System.Windows.xaml中定义了大多数控件的样式。
将ThemeResources.xaml和System.Windows.xaml添加到项目中,由于System.Windows.xaml引用了ThemeResources.xaml中定义的资源,所以在System.Windows.xaml的根元素下添加一个ResourceDictionary来引用ThemeResources.xaml(否则在运行时会抛出找不到资源的异常):
<ResourceDictionary.MergedDictionaries>
 
<ResourceDictionary Source="ThemeResources.xaml"/>
 
</ResourceDictionary.MergedDictionaries>

然后在我们的CustomTheme.xaml中也添加一个对System.Windows.xaml引用的ResourceDictionary:
<ResourceDictionary.MergedDictionaries>
 
<ResourceDictionary Source="System.Windows.xaml"/>
 
</ResourceDictionary.MergedDictionaries>

现在这几个文件的关系是:App.xaml引用了CustomTheme.xaml,CustomTheme.xaml引用了System.Windows.xaml,System.Windows.xaml引用了ThemeResources.xaml。也就是说,在应用运行时,这几个XAML会被全部加载。
至此,我们的应用中已经包含了Windows Phone的几乎所有资源和样式,但无论我们怎么修改它们的值,都不会影响应用在运行时呈现的外观。因为我们所有的模版和页面元素依然引用了系统内置的资源,而这些资源是不可覆盖的。
这里有个奇怪的现象,如果我们修改了这些资源的值,是可以在设计器中看到效果的,但丝毫不会影响运行时的效果,我相信这也是一个迟早要修复的Bug。
回到正题,既然我们已经包含了Windows Phone的几乎所有的资源和样式,那还何必去覆盖系统预置的资源和模版呢?直接使用我们自己的不就好了吗?
没错,就是这样。
我们观察到Windows Phone内置的资源和样式的名称都以“Phone”开头,非常有规律,也就非常容易替换。所以接下来我们在整个项目(或解决方案,取决于你的实际情况)里搜索x:Key=”Phone这个字符串,将其替换为x:Key=”Custom,这样会将所有资源的名称修改为CustomXXX;然后在搜索{StaticResource Phone开头的字符串,将其替换为{StaticResource Custom,这样会把所有对系统资源的引用修改为对应用内资源的引用。
如下图所示:

 

Windows Phone自定义主题

2012-03-12 09:12 by Windie Chai, 129 visits, 收藏, 编辑

我们知道Windows Phone默认的主题系统是由黑白两色为背景和一些强调色组成的,用户可以随意切换。通常来说,应用开发者无需关心这一部分,系统会去更新相关的资源,然后再体现在应用中。

但有一些时候,我们基于品牌等因素的考量,可能不想使用Windows Phone的默认主题。比如我开发的“豆芽”是豆瓣网的一个客户端,我希望尽可能贴近豆瓣网本身清新的风格,而不是给用户呈现一个和豆瓣网风格大相径庭的黑色背景的界面;再比如我想让应用使用Windows Phone的默认字体(等线),而不是SDK的默认字体(雅黑)。

这些都需要我们去自定义应用的主题。

在介绍如何创建自定义主题之前,先来简单的描述一下Windows Phone主题的原理。

在Windows Phone中,系统预定义了许多资源,这些资源包括了画笔、颜色、字体、粗细、字号、文本样式等等最基本的元素(详细的资源名称可以查看这里)。此外,Windows Phone中的所有控件都会有自己的样式,样式中还包括了定义控件布局的模板,而模板又利用系统内置的资源定义了控件在各种状态下的外观(所以我们在XAML中随处可以见类似{StaticResource PhoneBackgroundBrush}这样的对内置资源的引用)。

所以我们可以想到,修改内置资源或者修改控件的样式都可以达到自定义主题的效果。

在早期的Windows Phone v7.0),我们可以使用前一种方式,只需要在应用中增加一个ResourceDictionary的XAML文件,里边添加若干和系统资源相同键名的资源,即可实现对系统资源的覆盖。

但这种方法在Mango (v7.1)中无效了,它被当作一个Bug修复了,所以我们只能另寻方法。代价最小的一种方法是在App初始化的时候动态的读取我们定义的ResourceDictionary,并替换系统内置资源。具体的步骤可以参考这里 ,我就不赘述了。

此外,还可以利用Mango带来的另外一个变化,新的Silverlight 4带来的“隐式样式”(Implicit Style)。隐式样式是指只有TargetType却没有指定Key的Style,在Silverlight 4中,会将这个Style应用到所有匹配的TargetType对象上。

我们可以利用“隐式样式”来更改内置控件的样式,只需要将需要修改的控件的样式添加到应用的ResourceDictionary中,将其Key值去掉即可(当然不去掉也可以,这就需要手工设置所有匹配控件的Style属性)。

但一般情况下,既然我们想要更改应用级别的主题,基本上我们会修改整套配色方案,如果单纯用“隐式样式”来实现的话,我们就需要实现所有控件的隐式样式,看起来似乎也不是一件简单的事情。补充:移动开发 , Windows Phone ,

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,