Silverlight為我們提供了功能非常強大的樣式,卻沒有提供快速應用樣式的方法,例如,我們不能像在WPF中那樣根據資源中的樣式的TargetType將樣式自動應用到所有目標型別的元素上(好消息是,在Silverlight 4中已經可以這麼做了)。Silverlight ToolKit(本文示例代碼引用的ToolKit版本:Microsoft Silverlight 3 Toolkit November 2009)中提供的預設樣式管理器(ImplicitStyleManager)稍微彌補了這一缺憾,通過預設樣式管理器,我們可以相對方便的在應用程式中使用主題。本文介紹了在Silverlight中如何使用主題。
前提條件:
在Silverlight 3中使用主題,首先需要在專案中添加對Silverlight ToolKit中的System.Windows.Controls.Theming.Toolkit程式集的引用。如果使用ToolKit中提供的主題(如TwilightBlue主題等),則需要添加相應主題程式集的引用或使用相應主題的樣式檔。
使用主題的幾種方式:
一、使用主題控制項
「主題控制項」這種叫法有些彆扭,但如果觀察一下主題的類繼承層次,會發現所有主題均從純虛類
System.Windows.Controls.Theming.Theme(簡稱Theme)中繼承,而Theme類則直接繼承自ContentControl,因此主題確實是一個控制項。
使用步驟:
1、添加對相應主題程式集的引用,例如,使用TwilightBlue主題需要添加對System.Windows.Controls.Theming.TwilightBlue程式集的引用。
2、將需要應用主題的元素放到主題控制項的內容中。
UserControl x:Class="ThemeSample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:TwilightBlueTheme="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.TwilightBlue" > <TwilightBlueTheme:TwilightBlueTheme > <StackPanel x:Name="LayoutRoot" Width="160" Margin="100" > <Button Content="Button" Margin="10" ></Button> <TextBox Text="TextBox" Margin="10"></TextBox> </StackPanel> </TwilightBlueTheme:TwilightBlueTheme> </UserControl>
效果預覽:
二、使用ImplicitStyleManager類提供的附加屬性
使用該方式時無需添加對相應主題程式集的引用,但是需要使用相應主題提供的樣式檔,例如使用TwilightBlue主題時需要System.Windows.Controls.Theming.TwilightBlue.xaml檔,如果已經正確安裝了ToolKit,應該能在C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Toolkit\Nov09\Themes\Xaml資料夾找到。
使用步驟:
1、將樣式檔添加到專案中,並將生成操作設置為「內容」。
2、對需要應用主題的元素設置附件屬性。
<UserControl x:Class="ThemeSample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Theming="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.Toolkit" > <StackPanel x:Name="LayoutRoot" Width="160" Margin="100" Theming:ImplicitStyleManager.ApplyMode="Auto" Theming:ImplicitStyleManager.ResourceDictionaryUri= "Themes/TwilightBlue.xaml"> <Button Content="Button" Margin="10" ></Button> <TextBox Text="TextBox" Margin="10"></TextBox> </StackPanel> </UserControl>
ApplyMode屬性有三個可選值: None, OneTime和Auto。
None: 不使用樣式
OneTime: 在頁面載入後接受一次指定的樣式
Auto: 在運行時動態添加的控制項也將會使用指定樣式
效果預覽:
三、使用CSharp代碼動態改變主題
該方式是第二種方式的CSharp實現,同樣不需要相應主題的程式集而只需相應主題的樣式檔。為方便演示,示例使用者控制項中添加了一個ComboBox用來動態改變主題。
示例代碼(XAML):
<UserControl x:Class="ThemeSample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" > <StackPanel x:Name="LayoutRoot" Width="160" Margin="100"> <Button Content="Button" Margin="10" ></Button> <TextBox Text="TextBox" Margin="10"></TextBox> <ComboBox SelectionChanged="ComboBox_SelectionChanged" Margin="10"> <sys:String>ShinyRed</sys:String> <sys:String>TwilightBlue</sys:String> </ComboBox> </StackPanel> </UserControl>
示例代碼(cs):
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Theming; namespace ThemeSample { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { string themeName = (sender as ComboBox).SelectedItem as string; if (string.IsNullOrEmpty(themeName)) return; Uri uri = new Uri(string.Format("Themes/{0}.xaml", themeName), UriKind.Relative); ImplicitStyleManager.SetResourceDictionaryUri(LayoutRoot, uri); ImplicitStyleManager.SetApplyMode(LayoutRoot, ImplicitStylesApplyMode.Auto); } } }
效果預覽:
Silverlight主題存在的缺陷:
ToolKit中提供的主題已經能基本滿足一般專案中使用主題的要求,但也存在以下缺陷:
1、通過將主題應用到容器控制項上或將容器控制項放在主題控制項的內容中的方式,可以將主題自動應用到控制項的所有子項目,但無法將主題直接應用到所有頁面或使用者控制項中(當然可以將頁面或使用者控制項作為子項目出現)。
2、更糟的是:ChildWindow咋辦?
在頁面或使用者控制項中應用的主題不能自動應用到打開的子視窗中,雖然我們可以對子視窗應用主題,但應用主題後的子視窗還是會留下很不協調的邊框,如下圖:
看來要實現對ChildWindow應用主題,還是要靠我們自己寫樣式和範本,這無疑給應用主題帶來了一些困難。同樣存在的好消息是,Silverlight 4中,主題已經可以應用到ChildWindow了,下圖是一個Window 7風格的ChildWindow:
全站熱搜
留言列表