当前位置: 首页 > news >正文

wp7中创建自定义主题(mango和非mango的简单对比)

  背景:前段时间做项目的时候,遇到这样一个问题,当我们在从非mango sdk升级到mango sdk时,把系统的默认主题切换到“Light”,应用程序自定义的主题不生效,通过查阅大量的资料,最终找到了solution,由于这段时间需要用这方面的知识,所以将其整理出来。如果有不对的地方,请大家多多指教,谢谢!

   wp7中系统提供给我们两种默认的系统主题:黑色和白色,但在某些情况下,我们需要实现当系统主题改变时,不会影响到我们的应用程序。所以,就需要使用系统自定义的主题。这里需要说明一点,在开发项目过程中,我们遇到这样的一个问题,在非mango中使用自定义的主题时(即修改Theme Resource中的key值到自己想要的),应用程序运行正常,而在mango中我们使用自定义主题时,应用程序没有生效,还是使用系统默认的主题。这个主要原因是,在非mango中使用Windows Phone v7.0SDK,自定义主题不会覆盖系统的主题,在mango中Windows Phone v7.1SDK微软将其认为是一个bug而修复,所以,在mango设备中我们使用key值来自定义主题行不通。

样式在资源中有两种声明方式,一种是带Key(键值)的一种是不带key(键值)的(是一种隐式转换,仅在mango中有生效)。带key的样式,不会自动应用的控件上,除非使用Style="{StaticResource PhoneTextTitle1Style}"引用该资源的键值。而不带key的样式,会自动应用到所有同类型的元素上。

   以下以Windows Phone v7.0和Windows Phone v7.1为例简单说明自定义主题的使用:

   一下主要以一个简单的例子做对比,首先看在Windows Phone v7.0中,在安装完sdk后,C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Design目录下有两个文件System.Windows.xaml和ThemeResources.xaml文件,一个是定义wp使用的控件样式文件,一个是资源文件(颜色,字体,画笔,字号和字体粗细等等)。如果我们要使用自定义的主题,我们需要将ThemeResources.xaml中的内容全部copy到app.xaml <Application.Resources> </Application.Resources>中,或者新建一个customtheme文件夹将自定义的主题都放入customtheme文件夹下面的customtheme.xaml中。在这里推荐使用后者,这样看起来比较清楚。本文是以第二种为例,我是将ThemeResources.xaml中的内容全部copy到我新建的文件夹下面customtheme.xaml中,在app.xaml<Application.Resources> </Application.Resources>中加入下面的代码(这样应用程序才会将我们自定义的主题加载进去):      

<ResourceDictionary>

  <ResourceDictionary.MergedDictionaries>

     <ResourceDictionar Source="UseCustomTheme\ThemeResources.xaml"/>

  </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

在ThemeResources.xaml中,我做如下修改:

    <!--<Color x:Key="PhoneForegroundColor">#FFFFFFFF</Color>-->

<Color x:Key="PhoneForegroundColor">#FF84F4FF</Color>

而TextBlock的定义如下:   

<Style x:Key="PhoneTextBlockBase" TargetType="TextBlock">

        <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>

        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>

        <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>

        <Setter Property="Margin" Value="{StaticResource PhoneHorizontalMargin}"/>

    </Style>

 

在MainPage.xaml中加入代码:

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

 

        <!--TitlePanel contains the name of the application and page title-->

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION"  Style="{StaticResource PhoneTextNormalStyle}"/>

            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0"  Style="{StaticResource PhoneTextTitle1Style}"/>

        </StackPanel>

 

        <!--ContentPanel - place additional content here-->

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <TextBlock Height="71" HorizontalAlignment="Left" Margin="128,159,0,0" Name="textBlock1" Text="自定义主题测试" VerticalAlignment="Top" Width="179" />

        </Grid>

  </Grid>

运行程序结果如下:

 

在测试程序中,我仅仅改变了程序的前景色。

同样的程序代码,我们升级sdk到mango,运行程序界面如下:

 

程序的并没有使用我们自定义的主题,原因上面已经提到,是因为微软把他当做一个bug在7.1的sdk中已经修复。那么,在7.1中我们如何实现自定义主题呢?

   7.1 的silverlight for windows phone是基于Siverlight4的,因此加入了隐式样式,即声明样式的时候不指定key,只有一个targetType。所以,我们可以在ThemeResources.xaml对TextBlock作如下修改:

    <Style TargetType="TextBlock" BasedOn="{StaticResource PhoneTextBlockBase}" >

        <Setter Property="Foreground" Value="#FF84F4FF"/>

    </Style>

那么,相应地,在应用该资源的时候也不需要使用Style="{StaticResource PhoneTextTitle1Style}引用资源的键值。

在MainPage.xaml中作如下修改:

    <Grid x:Name="LayoutRoot" Background="{StaticResource CustomBackgroundBrush}">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

   <!--TitlePanel contains the name of the application and page title-->

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" /> <!--Style="{StaticResource PhoneTextNormalStyle}"/>-->

            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0"/> <!--Style="{StaticResource PhoneTextTitle1Style}" />-->

        </StackPanel>

 

        <!--ContentPanel - place additional content here-->

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <TextBlock Height="71" HorizontalAlignment="Left" Margin="128,159,0,0" Name="textBlock1" Text="自定义主题测试" VerticalAlignment="Top" Width="179" />

        </Grid>

</Grid>

运行结果如下图所示(分别是在系统的主题是dark和light运行效果):

 但是在windows phone7.0sdk中运行时正常的。

结论:windows phone7.0sdk中支持自定义的主题覆盖默认主题,但在windows phone7.1sdk中MS将其认为是一个bug进行了修复。

解决办法1:

我们可以在应用程序初始化的时候动态的读取我们定义的ResourceDictionary,并替换系统内置资源。首先,注释掉App.xaml中下面的代码:<ResourceDictionary>

  <ResourceDictionary.MergedDictionaries>

     <ResourceDictionar Source="UseCustomTheme\ThemeResources.xaml"/>

  </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

其次,在App.xaml.cs中加入如下代码:

            var dictionaries = new ResourceDictionary();

            string source = String.Format("/CustomTheme;component/UseCustomTheme/ThemeResources.xaml");

            var themeStyles = new ResourceDictionary { Source = new Uri(source, UriKind.Relative) };

            dictionaries.MergedDictionaries.Add(themeStyles);

            ResourceDictionary appResources = App.Current.Resources;

            foreach (DictionaryEntry entry in dictionaries.MergedDictionaries[0])

            {

                SolidColorBrush colorBrush = entry.Value as SolidColorBrush;

                SolidColorBrush existingBrush = appResources[entry.Key] as SolidColorBrush;

                if (existingBrush != null && colorBrush != null)

                {

                    existingBrush.Color = colorBrush.Color;

                }

            }

切记:这段代码要加在InitializeComponent()初始化之前,负责不起效果。

解决办法2:

在App.xaml.cs中加入如下代码:

            (App.Current.Resources["PhoneForegroundBrush"] as SolidColorBrush).Color = Color.FromArgb(255, 0, 92, 200);(这个颜色根据需要调整)

            (App.Current.Resources["PhoneBackgroundBrush"] as SolidColorBrush).Color = Colors.Black;

解决办法3:

上面已经提到在7.1SDK中不能通过修改key值来修改应用程序主题,所以我们做如下修改:

首先,新add一个CustomTheme.xaml进入工程中,引入C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Design下面的

System.Windows.xaml和ThemeResources.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.MergedDictionaries>

        <ResourceDictionary Source="System.Windows.xaml"/>

    </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

注意:这里有个奇怪的现象CustomTheme.xaml不能放在新建的文件夹下,否则运行时抛出异常所以,需要将CustomTheme.xaml放在当前根目录下面。

同时在System.Windows.xaml中引入ThemeResources.xaml。由于App.xaml引用了CustomTheme.xaml,CustomTheme.xaml引用了 System.Windows.xaml,System.Windows.xaml引用了ThemeResources.xaml。因此,我们的应用中已经包含了Windows Phone的几乎所有资源和样式。

最后把System.Windows.xaml和ThemeResources.xaml中系统的内置资源和样式做修改,因为Windows Phone内置的资源和样式的名称都以“Phone”开头,所以将x:Key=”Phone替换为x:Key=”Custom,{StaticResource Phone替换为{StaticResource Custom,完成以上修改后别忘了修改需要引用资源的地方Style="{StaticResource  CustomTextNormalStyle}"而非Style="{StaticResource  PhoneTextNormalStyle}"。

运行程序结果如下:

 

 

转载于:https://www.cnblogs.com/zeiier86/archive/2012/04/10/2440242.html

相关文章:

  • MINA网络通信框架
  • Foxmail 使用技巧
  • 动态文档制作
  • datagridview属性说明
  • PHP中没有编译CURL - 请联系主机商
  • 《统一沟通-微软-实战》-6-部署-1-前端服务器-2-准备基础结构和系统
  • gnome3 安装
  • Evernote要做用户的第二大脑
  • 我的家庭私有云计划-18
  • 使用type 为image的图片,但不提交form的解决办法。
  • Redmine在项目管理中的应用
  • whitespace error: trailing space at end of line
  • 厚积薄发,丰富的公用类库积累,助你高效进行系统开发(6)----全屏截图、图标获取、图片打印、页面预览截屏、图片复杂操作等...
  • 我的相亲日记_17(原创连载)
  • nagios监控http(借助脚本)
  • 【Leetcode】101. 对称二叉树
  • 07.Android之多媒体问题
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • Docker下部署自己的LNMP工作环境
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • golang中接口赋值与方法集
  • Java面向对象及其三大特征
  • SegmentFault 2015 Top Rank
  • Spring-boot 启动时碰到的错误
  • STAR法则
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 聊聊flink的BlobWriter
  • 异步
  • 怎么把视频里的音乐提取出来
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • C# - 为值类型重定义相等性
  • HanLP分词命名实体提取详解
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #DBA杂记1
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • $refs 、$nextTic、动态组件、name的使用
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (四) 虚拟摄像头vivi体验
  • (转)LINQ之路
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • ***详解账号泄露:全球约1亿用户已泄露
  • ../depcomp: line 571: exec: g++: not found
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .net 按比例显示图片的缩略图
  • .net和jar包windows服务部署
  • .NET轻量级ORM组件Dapper葵花宝典
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • [ 渗透测试面试篇 ] 渗透测试面试题大集合(详解)(十)RCE (远程代码/命令执行漏洞)相关面试题
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [04] Android逐帧动画(一)
  • [ai笔记4] 将AI工具场景化,应用于生活和工作
  • [bzoj2957]楼房重建
  • [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)