Silverlight4中实现Theme的动态切换

  Silverlight一般用来开发一些企业的应用系统,如果用户一直面对同一种风格的页面,时间长了难免厌烦,所以一般都会提供好几种风格及Theme供用户选中,下面就来说一下如何在不重新登录系统的情况下,实现风格的动态切换。我们写一个Demo来说明一下。

  新建一个Silverlight的项目,并添加一个默认的站点,先来写一下页面吧,简单起见,只放两个控件,MainPage的代码如下:

<UserControl x:Class="SilverlightChangeTheme.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
      <Button Content="ChangeTheme" Height="23" HorizontalAlignment="Left"
              Margin="40,66,0,0" Name="button1" VerticalAlignment="Top"
              Width="108" Click="button1_Click" Style="{StaticResource BtnStyle}" />
      <TextBlock Height="23" HorizontalAlignment="Left"
                 Margin="58,37,0,0" Name="textBlock1"
                 Text="文字样式" VerticalAlignment="Top"
                 FontSize="14" Width="101" Style="{StaticResource txtStyle}" />
   </Grid>
</UserControl>

效果图如下:

就是一个简单的按钮和一个TextBlock,下面要实现的效果是点击按钮实现文字和按钮字体颜色改变(样式要从资源文件加载);

那么既然要实现切换风格,首先要有资源文件,我们先建两个Silverlight Resource Dictionary,红色风格和蓝色风格,命名为Blue.xaml和Red.xaml,代码如下:

Red.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   <Style TargetType="Button" x:Key="BtnStyle">
      <Setter Property="Foreground" Value="Red" />
   </Style>
   <Style TargetType="TextBlock" x:Key="txtStyle">
      <Setter Property="Foreground" Value="Red" />
   </Style>
</ResourceDictionary>

Blue.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   <Style TargetType="Button" x:Key="BtnStyle">
      <Setter Property="Foreground" Value="Blue" />
   </Style>
   <Style TargetType="TextBlock" x:Key="txtStyle">
      <Setter Property="Foreground" Value="Blue" />
   </Style>
</ResourceDictionary>

由于MainPage中已经绑定了资源文件中的样式,所以系统启动时就必须加载某一个样式文件,就是所谓的默认样式,所以要加一个静态类,来实现系统启动时加载默认样式和切换样式,代码如下:

ThemeHelper.cs

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightChangeTheme
{
   public static class ThemeHelper
   {
      /// <summary>
      /// 加载样式文件到Application.Current.Resources
      /// </summary>
      /// <param name="theme"></param>
      public static void LoadTheme(string theme)
      {
         ResourceDictionary rd = new ResourceDictionary();
         if (theme.Length == 3)
         {
            Application.LoadComponent(rd, new Uri("/SilverlightChangeTheme;component/Red.xaml", UriKind.Relative));
         }
         else
         {
            Application.LoadComponent(rd, new Uri("/SilverlightChangeTheme;component/Blue.xaml", UriKind.Relative));
         }
         //清空Application.Current.Resources,存放新的样式
         if (Application.Current.Resources.Count > 0)
         {
            Application.Current.Resources.Clear();
         }
         Application.Current.Resources.MergedDictionaries.Add(rd);
      }

      /// <summary>
      /// 从Application.Current.Resources中获取指定名称的样式
      /// </summary>
      /// <param name="name"></param>
      /// <returns></returns>
      public static object FindResource(string name)
      {
         if (App.Current.Resources.Contains(name))
         {
            return App.Current.Resources[name];
         }
         else
         {
            return null; //这里返回NULL,如果没有控件会变成系统默认样式。
         }
      }
   }
}

然后在App.xaml.cs中,在Application_Startup方法中添加如下代码:

private void Application_Startup(object sender, StartupEventArgs e)
      {
         //加载默认样式
         ThemeHelper.LoadTheme("Blue");
         this.RootVisual = new MainPage();
      }

这样启动时就会自动加载蓝色的风格了,效果图下:

然后,给MainPage的Button添加事件,实现样式的切换,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightChangeTheme
{
   public partial class MainPage : UserControl
   {
      bool IsRed = false;
      public MainPage()
      {
         InitializeComponent();
      }

      private void button1_Click(object sender, RoutedEventArgs e)
      {
         if (IsRed)
         {
            //加载样式到Application.Current.Resources
            ThemeHelper.LoadTheme("Blue");
            IsRed = false;
         }
         else
         {
            //加载样式到Application.Current.Resources
            ThemeHelper.LoadTheme("Red");
            IsRed = true;
         }
         //运行时,更新样式必须重新设置每个控件的Style,然后调用this.UpdateLayout()方法更新页面。
         button1.Style = ThemeHelper.FindResource("BtnStyle") as Style;
         textBlock1.Style = ThemeHelper.FindResource("txtStyle") as Style;
         this.UpdateLayout();
      }
   }
}

这样就实现了样式的切换,需要注意的是系统启动后切换样式,要在代码中重新设置每个控件的Style,然后调用this.UpdateLayout()方法更新页面。

当然,如果有多窗体的话,没有打开的话是不需要设置的,只需要设置已经显示的控件。

 

补充知识:

关于Uri路径的写法。

XAML文件的相对Uri访问, 如<Image Source="silverlight.png" />或是<Image Source="./silverlight.png" />,

在子文件夹里的可以用<Image Source=”./images/sl.jpg” />访问到
最保险的方式是采用特有的程序集资源URI访问,格式为
<Image Source="/{assemblyShortName};component/Foo.jpg"/>, 这种方式还可以引用到xap中的其他程序集中的图片

 

修改我们的两个图片的引用方式为

<Image Source="/SilverlightApplication1;component/silverlight.png"/>
<Image Source="/SilverlightApplication1;component/images/sl.jpg" Height="100"/>  

 

点击这里下载源码

 

时间: 2024-08-01 16:50:24

Silverlight4中实现Theme的动态切换的相关文章

android-安卓开发 如何在代码中动态切换fragment加载的布局文件?

问题描述 安卓开发 如何在代码中动态切换fragment加载的布局文件? viewpager和fragment一起用的时候,比如有啊,吧,a,b,c,三页,一开始显示的是a,我想当用户滑到b和c时先显示的是一个loding的圆环进度条,之后再显示这个fragment的内容,请问应该如何做? 解决方案 上面说的是fragment之间的切换,你这个问题直接用view.setVisibility()方法控制进度条隐藏或显示就好了,也可以吧进度条放在Dialog或pupopWindow等当中控制show

动态切换tableView中的cell的种类

动态切换tableView中的cell的种类 为什么要动态切换tableView中cell的种类呢?如果项目经理不出这种需求,你也就见不到这篇文章了:) 效果: 源码: 首先,你要准备3种cell,直接继承系统的就行了. // // RootViewController.m // ChangeCell // // Copyright (c) 2014年 Y.X. All rights reserved. // #import "RootViewController.h" #import

如何在wpf中动态切换controltemplate?

问题描述 如何在wpf中动态切换controltemplate? RT 我想实现一个自定义树形控件,想动态切换controltemplate,比如有多个controltemplate,可以动态加载.这种思路可行吗?如果可行该如何实现呢?谢谢~~ 解决方案 MVVM开发的话,通过Style的Tiggers来做,添加DataTrigger,绑定ViewModel的一个属性,改变属性值就可以达到切换模板的目的了.

Android动态切换主题

软件换肤从功能上可以划分三种: 1) 软件内置多个皮肤,不可由用户增加或修改: 最低的自由度,软件实现相对于后两种最容易. 2) 官方提供皮肤供下载,用户可以使用下载的皮肤: 用户可选择下载自己喜欢的皮肤,有些玩家会破解皮肤的定制方法,自己做皮肤使用,或者传到网上给大家用. 参考:http://blog.csdn.net/zhyooo123/article/details/6697186 3) 官方提供皮肤制作工具或方法,用户可自制皮肤. 关于主题和样式: 就像style一样,主题依然在<sty

程序实现多国语言的动态切换解决方案

实现思想: 传统的做法是把所有的资源都放到动态库中,一种语言一个动态库,程序运行的时候通过加载不同的动态库来实现多语言功能.这样做的缺点是不能动态切换语言,如果更换语言后必须重新启动软件.当然,没有人会需要经常的切换语言玩儿,但是采用动态库的方法,如果程序需要修改资源的话,就要更新所有的动态库,这是一个非常枯燥而且容易出现疏漏的工作. 我的方法是把所有用到的字符串都放到文件中,一种语言一个文件,根据选择的语言到对应的文件中去加载字符串.这样不但可以动态切换语言,而且用户可以根据需要自己添加新的语

在PPT2010中设置幻灯片的随机切换

  在最新的PowerPoint 2010版本中,增加了许多令人眼花缭乱并且惊叹不已的幻灯片切换效果,然而细心的用户可以发现,其中原有版本中所包含的"随机切换效果"的选项现在消失了,也就是说用户必须为各页幻灯片指定一个固定的切换方式,而不能使用各页随机出现不同的切换方式. 在PPT2010中设置幻灯片的随机切换 在PPT2010中设置幻灯片的随机切换 这不得不说是2010版本的一个比较大的遗憾,但幸好我们还有VBA,可以弥补这个遗憾,可以使用以下代码设置各页幻灯片使用随机的切换方式:

mdi toolbar动态切换-MFC 多文档程序 怎样 动态切换ToolBar

问题描述 MFC 多文档程序 怎样 动态切换ToolBar 我的应用场合是这样的: VS10创建的MDI 多文档程序,有2个文档模板,分别对应View1 和View2 两种视图,View1对应工具条ToolBar1 ,View2对应工具条Toolbar2. 我想实现:View1 激活时,显示ToolBar1: View2激活时,显示ToolBar2. 目前,我在CChildFrame中响应 WM____CHILDACTIVATE 消息,代码如下: void CChildFrame::OnChil

Android实现动态切换组件背景的方法_Android

本文所述的程序实现的功能为在软件中动态的选择组件背景,系统皮肤,自定义吐司背景等. 为实现这一要求,就需要用到安卓中的SharedPrefence的功能,首先在设置里面写一个控件,设置一个点击监听器,点击的时候显示一个Alert选择弹窗,让你进行选择,对这个弹窗再设置一个点击监听器(onItemListener),点击到具体某个的时候,把对应的点击id保存到sahredprefence里面去,这样,其他地方就可以从这里取得设置里选择的值,进行动态个性化处理. 具体代码如下: 1.设置选择的操作:

ssh 多数据源问题!-spring多数据源动态切换问题

问题描述 spring多数据源动态切换问题 一个总公司托管了N个子公司,每个子公司对应自己的数据库,我的程序实现每个子公司根据用户名登录的时候,只访问自己的数据库,而且公司的数目还在增加,这就涉及到了动态切换多数据源的问题!,还涉及到多个用户登录的时候的并发问题!急求解决,谢谢! 解决方案 目前很多项目中只能配置单个数据源,那么如果有多个数据源肿么办?Spring提供了一个抽象类AbstractRoutingDataSource,为我们很方便的解决了这个问题.1.写一个DynamicDataSo