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-11-10 20:15:27

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

Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法(转)

一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基本上没有什么问题,但唯一可能出现问题的就是在hibernate做添加操作生成主键策略的时候.因为我们都知道hibernate的数据库本地方言会针对不同的数据库采用不同的主键生成策略. 所以针对这一问题不得不采用自定义的主键生成策略,自己写一个主键生成器的表来维护主键生成方式或以及使用其他的方式来生成

动态切换tableView中的cell的种类

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

spring框架中多数据源创建加载并且实现动态切换的配置实例代码

原文:spring框架中多数据源创建加载并且实现动态切换的配置实例代码 源代码下载地址:http://www.zuidaima.com/share/1774074130205696.htm 在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库.我们以往在spring和hibernate框架中总是配置一个数据源,因而sessionFactory的dataSource属性总是指向这个数据源并且恒定不变,所有DAO在使用sessionFa

动态切换 web 报表中的统计图类型

需求: 报表以图形方式,也就是我们常说的“图表”形式展示时,不同的用户对图形类型有不同的要求,希望能够动态切换统计图类型,例如实现柱形图.条形图.折线图等图形间的动态切换. 思路: 常见的做法是在报表中多个单元格中生成不同的统计图,然后通过参数动态隐藏行来实现图形类型切换,但此种方法需要制作大量的图形图表,工作量较大,而且大量隐藏单元格会耗用内存,在性能上也有一定影响. 当然,肯定还会有别的方式……我们在制作统计图时会发现,绝大多数统计图设置方式基本类似,只需要设置分类轴.系列即可生成统计图.而

(转) Android 全屏控制:动态切换全屏和非全屏

转自:http://blog.csdn.net/michaelpp/article/details/7302308 动态切换全屏和非全屏: package com.screen;   import android.app.Activity;  import android.os.Bundle;  import android.view.View;  import android.view.WindowManager;  import android.view.View.OnClickListen

使用React+Umi+Ant Design Pro实现生产环境动态切换主题,支持暗黑主题

投入前端开发也有1年的时间了,我还是很菜.在开发中还是很多技巧以及经验不够,写文章也是文笔不行,不过好在写的内容意思大概都能看懂.这次就来介绍一下我在开发过程中遇到的一些问题以及处理技巧. 两月前刚开始试用umi这个React的框架,使用AntD Pro创建好项目后,着实熟悉了几天,不过熟悉这个框架后,就觉得阿里的大佬还是牛.佩服. 事情是这样的,我们能够在AndD Pro的在线预览上看到能够动态切换主题.而实际拉下来的模板中却没有这个功能.我就开始了对比源码. 算了,先上一下项目目录结构吧,不

Spring整合多数据源实现动态切换

在实际项目中时常需要连接多个数据库,而且不同的业务需求在实现过程当中往往需要访问不同的数据库. jdbc.properties配置文件,配置多个dataSource ##########################MySQL##################################### hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect connection.driver_class=com.mysql.jdbc.

实现flex LinkBar 组件 动态切换ico图标

<?xml version="1.0" encoding="utf-8"?><s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"                        xmlns:s="library://ns.adobe.com/flex/spark"                        xmlns:mx="

mybatis动态切换数据源

(#)背景:由于业务的需求,导致需要随时切换15个数据源,此时不能low逼的去写十几个mapper,所以想到了实现一个数据源的动态切换 首先要想重写多数据源,那么你应该理解数据源的一个概念是什么,DataSourceTransactionManager这个类就是spring中对于数据源的封装,其中DataSource做为 他的一个成员.接下来我们要介绍一下我们切换动态数据源需要使用的类,AbstractRoutingDataSource,先来看看这个类的源码 首先看看这几个变量,targetDa