转: Silverlight的样式设置及管理(Theme)

来源:互联网 发布:网络印刷报价系统 编辑:程序博客网 时间:2024/06/05 19:34

 

原文地址:
http://weblogs.asp.net/lduveau/archive/2009/11/17/skin-your-silverlight-3-app-with-implicit-style-manager.aspx
使用默认样式管理器管理你的Silverlight应用的外观
      Silverlight 3没有像WPF的默认样式或是asp.net的主题特性, 举例来说我们无法像ASP.NET那样让程序的每个按钮自动的使用一个样式.
      在Silverlight 3里你需要在每个控件上明确的设置样式.
      好消息是你能在Silverlight Toolkit里找到默认样式管理器(ImplicitStyleManager)控件, 它允许你通过在一个容器控件里定义两个附加属性来让容器内部的控件使用一个默认样式.
在Silverlight 3里使用主题样式
       在一个XAML资源字典文件里定义你的样式并且设置它的生成操作为"内容(Content)".然后在页面的一个容器控件上通过"ResourceDictionaryUri"附加属性来引用这个文件:
复制内容到剪贴板
代码:
<Canvas themingToolkit:ImplicitStyleManager.ApplyMode="OneTime"            themingToolkit:ImplicitStyleManager.ResourceDictionaryUri="Assets/ShinyBlue.xaml">
ApplyMode有三个可选值: None, OneTime和Auto
       None: 不使用样式
       OneTime: 在页面加载后接受一次指定的样式
       Auto: 在运行时动态添加的控件也将会使用指定样式
在容器内部(我们例子里是canvas), 按通常方式定义一些的控件:
复制内容到剪贴板
代码:
<TextBox Text="TextBox" Width="125" />
<PasswordBox Width="125" />
<ProgressBar IsIndeterminate="False" Maximum="1" Value="0.5"/>
<RadioButton Content="RadioButton 1" IsChecked="True" />
<RadioButton Content="RadioButton 2"/>
<CheckBox Content="CheckBox 1"/>
<CheckBox Content="CheckBox 2" IsChecked="True"/>
    […]
在运行的时候他们会自动使用我们指定的样式:

如果不想自己从头开始创建一个主题样式, 你也可以从toolkit里找到一些例子.

http://www.codeplex.com/wikipage?ProjectName=Silverlight&title=Silverlight%20Toolkit%20Overview%20Part%203&referringTitle=Home
这些主题所的XAML文件可以在安装toolkit后在本地找到,如果安装了2009年10月的工具包,那么本地路径是:
C:/Program Files/Microsoft SDKs/Silverlight/v3.0/Toolkit/Oct09/Themes/Xaml

在这个例子使用了ShinyBlue.xaml这个主题样式并通过默认样式管理器加载了它.
你可以在Expression Community Gallery找到更多的样式http://gallery.expression.microsoft.com/
特定主题样式控件(Specific Theme controls)
你也可以使用在Toolkit里的主题容器(Theme Containers) 控件来使用主题样式. 这些控件的内部其实是使用了默认样式管理器和xaml资源文件.
使用ShinyBlue主题可以像下面这样简单:
复制内容到剪贴板
代码:
<shinyBlue:ShinyBlueTheme>
    <Grid>
        ...
    </Grid>
</shinyBlue:ShinyBlueTheme>
这里的shinyBlue前缀指向包含ShinyBlue主题控件的程序集(在toolkit中):
xmlns:shinyBlue="clr-namespace:System.Windows.Controls.Theming;
assembly=System.Windows.Controls.Theming.ShinyBlue"
运行时改变主题(Changing Theme at runtime)
       假设你有几个主题样式并且想让你的用户能在使用程序的时候自己切换这些主题.
在我们这个例子里我增加另外的主题(ShinyRed), 从toolkit里找到这两个文件都移动到我们项目的Assets/Theme文件夹.

不要忘记修改这两个文件的生成操作为内容(Content).
让我们在页面上增加一个"样式选择器", 包括一个下拉列表和按钮.
复制内容到剪贴板
代码:
<ComboBox x:Name="cbThemes">
    <ComboBoxItem Content="ShinyBlue" Tag="ShinyBlue.xaml" />
    <ComboBoxItem Content="ShinyRed" Tag="ShinyRed.xaml"/>
</ComboBox>
<Button Content="Apply" Click="Button_Click" />
在按钮点击事件里得到选择的主题, 并使用默认样式管理器的一些静态方法让控件接受样式:
复制内容到剪贴板
代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
    if (cbThemes.SelectedItem != null)
    {
        Uri uri = new Uri(String.Format("Assets/Themes/{0}",
((ComboBoxItem)cbThemes.SelectedItem).Tag.ToString()), UriKind.Relative);
        ApplyTheme(uri);
    }
}
private void ApplyTheme(Uri uri)
{
    ImplicitStyleManager.SetResourceDictionaryUri(LayoutRoot, uri);
    ImplicitStyleManager.SetApplyMode(container, ImplicitStylesApplyMode.Auto);
    ImplicitStyleManager.Apply(container);
}
现在我们能在运行时切换当前的主题了:


动态列示可用的主题(Dynamic list of available Themes)

让我们进一步在运行时列出可用的主题样式.
通过small unzip utility for Silverlight(http://www.sharpgis.net/post/2009/04/21/REALLY-small-unzip-utility-for-Silverlight.aspx)的帮助我们能自动的填充下拉列表(下面的代码假设你的xaml样式文件存放在Assets/Themes文件夹并且只存在这些文件):
复制内容到剪贴板
代码:
public DynamicStyle()
{
    InitializeComponent();
this.Loaded += new RoutedEventHandler(DynamicStyle_Loaded);
}
void DynamicStyle_Loaded(object sender, RoutedEventArgs e)
{
    WebClient wc = new WebClient();
    wc.OpenReadCompleted += (s, args) =>
    {
        if (args.Error == null)
        {
            UnZipper unzip = new UnZipper(args.Result);
List<ComboBoxItem> lstComboBoxItem = new List<ComboBoxItem>();
ComboBoxItem item;
            string fileName;
foreach (string filePath in unzip.GetFileNamesInZip())
            {
                if (filePath.StartsWith("Assets/Themes"))
                {
                    fileName=filePath.Replace("Assets/Themes/", string.Empty)
.Replace(".xaml", string.Empty);
item = new ComboBoxItem();
                    item.Content = fileName;
                    item.Tag = filePath;
                    lstComboBoxItem.Add(item);
                }
            }
            cbThemes.ItemsSource = lstComboBoxItem;
        }
    };
    wc.OpenReadAsync(new Uri("FunWithImplicitStyleManager.xap",
UriKind.RelativeOrAbsolute));
}
UnZipper是上面链接提供的一个工具类, 在提供的源代码里能找到.
注意你也可以增加代码功能在一个用户会话期间一直使用选择的主题(甚至是通过IsolatedStorage让他一直起作用)
源代码地址:http://cid-0e564ed4426a5ecc.skydrive.live.com/self.aspx/Public/Code/Silverlight/Silverlight%203/FunWithImplicitStyleManager.zip