SilverLigth 學習筆記--控制 Silverlight控件樣式(轉)

 1、內聯方式--即直接在控件內部利用其屬性進行設置

<UserControl x:Class="RemoveTextBoxBorder.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Button Content="Button" Height="75" Width="125" BorderBrush="Green" Foreground="Blue" />
    </Grid>
</UserControl>

  2、全局方式--在 App.xaml Resources 文件中進行定義

  當你在VS2008中創建Silverlight項目中,你會得到一個名叫 "App.xaml"的文件,此文件格式如下:

 <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="RemoveTextBoxBorder.App"
             >
    <Application.Resources>
    </Application.Resources>
</Application>

  在此文件中你可以定義自己的樣式,定義樣式採用如下格式:

 <Style x:Key="樣式名" TargetType="樣式所針對的控件類型">
   <Setter Property="控件屬性名" Value="控件屬性值" />
 </Style>

在本示例中我們在此文件加入如下樣式定義,加入後的App.xaml文件內容如下

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="RemoveTextBoxBorder.App"
             >
    <Application.Resources>
        <Style x:Key="ButtonStyleOne" TargetType="Button">
            <Setter Property="BorderBrush" Value="Green" />
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="BorderThickness" Value="4,4,4,4" />
        </Style>
        <Style x:Key="ButtonStyleTwo" TargetType="Button">
            <Setter Property="BorderBrush" Value="Blue" />
            <Setter Property="Foreground" Value="Green" />
        </Style>
    </Application.Resources>
</Application>

  然後我們在控件的XAML文件中引用所定義的樣式

<UserControl x:Class="RemoveTextBoxBorder.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Button Content="Button" Height="75" Width="125" Style="{StaticResource ButtonStyleOne}"  />       
    </Grid>
</UserControl>

 

  3、在 C#代碼中動態設置控件樣式

  爲了在代碼中引用此控件,我們必須要爲此控件命名,在此我們命名爲"MyButton"

  <Button x:Name="MyButton" Content="Button" Height="75" Width="125" />    

  然後在Page.xaml的code-behind 文件中,在其構造函數中加入如下代碼:

  MyButton.Style = Application.Current.Resources["ButtonStyle"] as Style;

  後臺代碼如下:

  public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            MyButton.Style = Application.Current.Resources["ButtonStyleOne"] as Style;
        }
    }

Silverlight2中的頁面元素的各個組成部分都可以分離出來作爲資源的一部分,以方便複用。

比如我們爲用戶控件添加一個顏色資源:

<UserControl.Resources>
    <Color x:Key="Green">#F722FF00</Color>
</UserControl.Resources>

然後我們需要在定義的按鈕和所畫的橢圓中使用{StaticResource KeyName}去使用該資源:

<Grid x:Name="LayoutRoot" Background="White">
<Button Height="56" Width="128" Content="Button" BorderThickness="2,2,2,2">
<Button.Background>
<SolidColorBrush Color="{StaticResource Green}"/>
</Button.Background>
</Button>
<Ellipse Height="56" HorizontalAlignment="Left" Margin="64,176,0,0" VerticalAlignment="Top" Width="112">
<Ellipse.Fill>
<SolidColorBrush Color="{StaticResource Green}"/>
</Ellipse.Fill>
</Ellipse>
</Grid>

效果如圖:

Magical Snap - 2008.12.03 16.54 - 001

 

樣式控制

Silverlight2中支持使用樣式,樣式也是資源的一部分。樣式使用Style標籤來指定。

下面我們指定了一個針對Button類型的樣式:

<UserControl.Resources>
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="#F722FF00" />
<Setter Property="Foreground" Value="#FFFF0000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</UserControl.Resources>

然後我們新添加一個Button,通過使用與資源使用相同的語法來爲新添加的一個Button使用該樣式:

<Grid x:Name="LayoutRoot" Background="White">
<Canvas>
<Button Width="128" Height="56" Canvas.Left="20" Canvas.Top="20"
Style="{StaticResource ButtonStyle1}" Content="Button1" />
<Button Width="128" Height="56" Canvas.Left="20" Canvas.Top="80"
Style="{StaticResource ButtonStyle1}" Content="Button2" />
</Canvas>
</Grid>

最終效果:

Magical Snap - 2008.12.03 17.36 - 002 

上面所提到的資源和樣式都是寫在用戶控件中,只能在用戶控件的範圍內使用。但如果要在整個應用程序中使用,則應該將樣式資源定義在Silverlight項目的App.xaml中:

<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="StyleSample.App">
<Application.Resources>
<!-- Resources scoped at the Application level should be defined here. -->
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="#F722FF00" />
<Setter Property="Foreground" Value="#FFFF0000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Application.Resources>
</Application>

但如果App.xaml中的樣式與用戶控件中的樣式名稱一樣,用戶控件中的樣式會覆蓋App.xaml中定義的樣式。

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="StyleSample.Page"
Width="640" Height="480">
<UserControl.Resources>
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Foreground" Value="#FF000000"/>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>
<Button Width="128" Height="56" Canvas.Left="20" Canvas.Top="20"
Style="{StaticResource ButtonStyle1}" Content="Button1" />
<Button Width="128" Height="56" Canvas.Left="20" Canvas.Top="80"
Style="{StaticResource ButtonStyle1}" Content="Button2" />
</Canvas>
</Grid>
</UserControl>

效果如下圖,可以看到按鈕成了白底黑子,而不是App.xaml中的綠底紅字。

Magical Snap - 2008.12.03 17.48 - 003

 

視覺狀態

視覺狀態主要是將元素的邏輯與視覺呈現分離開來。它使得頁面的換膚功能相對更容易。

理解視覺狀態首先需要明白4個概念:部件、視覺狀態、狀態遷移和狀態組。

部件 (Parts)
部件就是控件模板中被命名的元素。程序可以根據該名稱定位到這些部件並進行邏輯操作。
Magical Snap - 2008.12.03 18.21 - 005
比如上面的水印文本框, 水印就是一個部件,在焦點成爲文本框時,水印將會消失。 狀態 (States)
視覺狀態就是控件定義的一系列的狀態,如上面水印文本框的Focus和UnFocus。 狀態過渡 (Transitions)
狀態過渡就是指控件從一個狀態過渡到另一個狀態,如水印文本框從UnFocus狀態過渡到Focus狀態。在這其中可以使用Storyboard來定義動畫效果。 狀態組 (StateGroups)
狀態組就是將控件所有的互斥狀態房子啊同一組,最終其狀態由所有組中的一個狀態來共同決定。
比如還是上面的文本框,它有3個狀態組:
Common:Normal、 MouseOver、 Disabled
Watermark:Unwatermarked、Watermarked
Focus:UnFocused、Focused
那麼文本框的狀態就必須從上面三個狀態組中取一個值來定義。如沒有任何操作在文本框的時候,其狀態爲Normal|Watermarked|UnFocused。

那麼,在上面的基礎上又引入了視覺狀態(VisualStates)和視覺狀態組(VisualStateGroups)的概念。

視覺狀態(VisualState)
視覺狀態就是指當控件處於某一個狀態的時候的視覺效果。比如一個按鈕在點擊之後,他的邊框將會變爲不同的顏色。 視覺狀態組(VisualStateGroups)
視覺狀態組包括了互斥的視覺狀態和所擁有的視覺狀態的過渡。

通過使用視覺狀態管理器(VisualStateManager)來管理視覺狀態和視覺狀態組,可以根據控件的邏輯改變控件的視覺效果。

更多關於視覺狀態的信息,請參考 “部件與狀態”模式

下面對視覺狀態所產生的XAML代碼做簡單說明,下面是上面例子中水印文本框中定義的視覺狀態管理代碼的一部分。

<Style TargetType="local:WatermarkedTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Extended"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WatermarkedTextBox">
<Grid x:Name="Root" >
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates">
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration="0" />
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name="Normal" />
<vsm:VisualState x:Name="MouseOver" />
<vsm:VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="DisabledVisual" 
Storyboard.TargetProperty="Opacity" To="0.5" Duration="0" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> <vsm:VisualStateGroup x:Name="WatermarkStates"> <vsm:VisualStateGroup.Transitions> <vsm:VisualTransition GeneratedDuration="0" /> </vsm:VisualStateGroup.Transitions> <vsm:VisualState x:Name="Unwatermarked" /> <vsm:VisualState x:Name="Watermarked"> <Storyboard> <DoubleAnimation Storyboard.TargetName="ContentElement"
Storyboard.TargetProperty="Opacity" To="0" Duration="0" /> <DoubleAnimation Storyboard.TargetName="Watermark"
Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> <vsm:VisualStateGroup x:Name="FocusStates"> <vsm:VisualStateGroup.Transitions> <vsm:VisualTransition GeneratedDuration="0" /> <vsm:VisualTransition To="Focused" GeneratedDuration="0:0:0.1" /> </vsm:VisualStateGroup.Transitions> <vsm:VisualState x:Name="Unfocused" /> <vsm:VisualState x:Name="Focused"> <Storyboard> <DoubleAnimation Storyboard.TargetName="ContentElement"
Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> <DoubleAnimation Storyboard.TargetName="Watermark"
Storyboard.TargetProperty="Opacity" To="0" Duration="0" /> <DoubleAnimation Storyboard.TargetName="FocusVisual"
Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>

來看代碼中的視覺狀態組爲WatermarkStates的這一部分:

<vsm:VisualStateGroup x:Name="WatermarkStates">
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration="0" />
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name="Unwatermarked" />
<vsm:VisualState x:Name="Watermarked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ContentElement"                                              
Storyboard.TargetProperty="Opacity" To="0" Duration="0" /> <DoubleAnimation Storyboard.TargetName="Watermark"
Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup>

代碼最前面的vsm表示前綴,在Style中以xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"定義,表示所有以vsm開頭的XAML語法所指定的屬性需要在assembly爲System.Windows.dll中定義過。

<vsm:VisualTransition GeneratedDuration="0" /> 定義了過渡該狀態組的狀態之間過渡的時間,這裏設置爲0,表示立即過渡到另一狀態。

<vsm:VisualState x:Name="Watermarked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ContentElement"      
Storyboard.TargetProperty="Opacity" To="0" Duration="0" /> <DoubleAnimation Storyboard.TargetName="Watermark"
Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> </Storyboard> </vsm:VisualState>

Watermarked這個狀態就通過Storyboard定義了一個效果,描述了在進入Watermarked狀態時,其ContentElement屬性文本立即變爲透明(因爲Duration爲0),而Watermark屬性則變爲不透明。

綜上所述可以看到,由於控件的狀態需要在不同的狀態組中取其互斥的一個值,然後將各個狀態組中的目標狀態的動畫效果綜合在一起,引發了在控件狀態變化的時候視覺效果也發生了變化。於是我們可以通過設置一個控件模板來定義不同的樣式和效果,而輕鬆的實現換膚功能。

 

部署

Silverlight項目的部署並不需要.NET Framework的支持,它的實際工作原理是通過HTTP將服務器上silverlight所生成的XAP壓縮包發到客戶端,由瀏覽器的silverlight插件去執行這個壓縮包而繪製出最終效果。因此其部署就是完全如同Flash一般使用HTML標籤中的object,然後定義好XAP包的路徑就可以了。

一般來說,一個silverlight項目所編譯生成的XAP包在項目文件下的bin的debug目錄中:

Magical Snap - 2008.12.04 13.12 - 001

通過在HTML中嵌入以下HTML代碼,將其中的source的值改爲所指定的XAP文件,就可以運行silverlight程序了。

<object data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="AnimationSample.xap"/>
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="2.0.31005.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" 
style="border-style: none"/> </a> </object>
注意上面代碼中的minRuntimeVersion,他指定了運行程序所必須的最小的silverlight版本。如果不滿足此條件,silverlight程序將可能不能正確運行。
而如果需要在IIS中部署silverlight程序的話,則必須要在IIS中的MIME中添加.xaml的解釋,如下圖。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章