在上一篇,介紹了Visual State Manager視覺狀態管理器,其中涉及到控件的樣式(Style)和模板(Template),本篇將詳細介紹樣式(Style)和模板(Template)在Silverlight項目中的應用,並介紹如何使用Blend設計樣式(Style)和模板(Template)。
在LOB(Line-of-Business)企業級應用項目開發中,爲了使項目的視覺效果多樣化,不只僅使用動畫效果,並且常常還須要修改部分控件的樣式(Style)和模板(Template)。 在Silverlight的控件包中,微軟已經定義了默認控件樣式和模板,開發人員能夠在這些默認的代碼上進行修改和調整,以達到項目需求。可是因爲默認的控件樣式和模板代碼過於冗長,手工修改起來相對複雜和繁瑣,對此,微軟封裝了一些新的功能在Blend中,方便開發人員和設計人員對模板和樣式進行控制。 在學習Blend控制樣式(Style)和模板(Template)前,仍是先快速瞭解一下樣式(Style)和模板(Template)。
樣式(Style),有HTML開發基礎的朋友對傳統的CSS樣式表並不陌生,HTML將全部公用的屬性代碼聚集到CSS文件中,使用CSS控制頁面的背景,控制表格的寬度,控制控件距離等。Silverlight中的樣式(Style)和CSS相同,容許設計人員和開發人員將控件的公用屬性定義到資源文件中,容許相同屬性控件自由調用,這樣不只提升了代碼的
複用性,並且保證了控件外觀在項目中的
一致性。
模板(Template),模板的概念在傳統的Web頁面開發中已經被引入,早期Dreamweaver由於支持建立Web模板設計,吸引了很多Web開發者。Silverlight中一樣引進了模板的概念。在Silverlight中,凡是繼承自System.Windows.Controls命名控件的控件都有一套默認的模板,設計人員和開發人員能夠基於默認模板的基礎上進行修改,建立自定義模板。
樣式(Style)和模板(Template)的定義
在Silverlight中,樣式和模板定義是很簡單的,由於不少屬性已經被封裝好,不須要自行建立,只須要調用就能夠了。簡單的演示代碼:
Style:
1
<
UserControl.Resources
>
2
<
Style
x:Key
="TextBoxStyle"
TargetType
="TextBox"
>
3
這裏定義具體樣式屬性
4
</
Style
>
5
</
UserControl.Resources
>
Template:
1 <UserControl.Resources>
2 <ControlTemplate x:Key="TextBoxTemplate" TargetType="TextBox" >
3 <Border BorderBrush="Orange" BorderThickness="3" CornerRadius="10"
4 Background="Red">
5
這裏定義具體模板
6 </Border>
7 </ControlTemplate>
8 </UserControl.Resources>
樣式(Style)和模板(Template)的使用
在Silverlight中樣式(Style)和模板(Template)都屬於控件資源,也就是說,二者均可以被定義在資源文件中,而在項目頁面中,僅需使用Style和Template屬性調用就能夠了。
Style:
1
<
TextBox
Style
={"StaticResource
TextBoxStyle"} Text
="樣式測試"
/>
Template:這個方法,也是Blend所支持的方法,下面咱們看看實例,進一步理解。
1
<
TextBox
Template
={"StaticResource
TextBoxTemplate"} Text
="模板測試"
/>
上面介紹了樣式和模板的最基本的用法。
在實際項目中,咱們常常把模板(Template)定義在樣式(Style)中,也就是將Template做爲一個屬性被賦值在Style中,這樣當樣式(Style)被應用在控件中時,新的模板也會同時加載。
例以下面Button樣式代碼,<Setter Property="Template"> Template是做爲Style的屬性被設置的:
代碼
1
<
ResourceDictionary
>
2
<
Style
x:Key
="ButtonStyle1"
TargetType
="Button"
>
3
<
Setter
Property
="Background"
Value
="#FF1F3B53"
/>
4
<
Setter
Property
="Foreground"
Value
="#FF000000"
/>
5
<
Setter
Property
="Padding"
Value
="3"
/>
6
<
Setter
Property
="BorderThickness"
Value
="1"
/>
7
<
Setter
Property
="BorderBrush"
>
8
<
Setter.Value
>
9
<
LinearGradientBrush
EndPoint
="0.5,1"
StartPoint
="0.5,0"
>
10
<
GradientStop
Color
="#FFA3AEB9"
Offset
="0"
/>
11
<
GradientStop
Color
="#FF8399A9"
Offset
="0.375"
/>
12
<
GradientStop
Color
="#FF718597"
Offset
="0.375"
/>
13
<
GradientStop
Color
="#FF617584"
Offset
="1"
/>
14
</
LinearGradientBrush
>
15
</
Setter.Value
>
16
</
Setter
>
17
<
Setter
Property
="Template"
>
18
<
Setter.Value
>
19
<
ControlTemplate
TargetType
="Button"
>
20
<
Grid
>
21
<
VisualStateManager.VisualStateGroups
>
22
<
VisualStateGroup
x:Name
="CommonStates"
>
23
<
VisualState
x:Name
="Normal"
/>
24
<
VisualState
x:Name
="MouseOver"
>
25
<
Storyboard
>
26
<
DoubleAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundAnimation"
Storyboard.TargetProperty
="Opacity"
>
27
<
SplineDoubleKeyFrame
KeyTime
="0"
Value
="1"
/>
28
</
DoubleAnimationUsingKeyFrames
>
29
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
>
30
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#F2FFFFFF"
/>
31
</
ColorAnimationUsingKeyFrames
>
32
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)"
>
33
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#CCFFFFFF"
/>
34
</
ColorAnimationUsingKeyFrames
>
35
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)"
>
36
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#7FFFFFFF"
/>
37
</
ColorAnimationUsingKeyFrames
>
38
</
Storyboard
>
39
</
VisualState
>
40
<
VisualState
x:Name
="Pressed"
>
41
<
Storyboard
>
42
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="Background"
Storyboard.TargetProperty
="(Border.Background).(SolidColorBrush.Color)"
>
43
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#FF6DBDD1"
/>
44
</
ColorAnimationUsingKeyFrames
>
45
<
DoubleAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundAnimation"
Storyboard.TargetProperty
="Opacity"
>
46
<
SplineDoubleKeyFrame
KeyTime
="0"
Value
="1"
/>
47
</
DoubleAnimationUsingKeyFrames
>
48
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)"
>
49
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#D8FFFFFF"
/>
50
</
ColorAnimationUsingKeyFrames
>
51
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
>
52
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#C6FFFFFF"
/>
53
</
ColorAnimationUsingKeyFrames
>
54
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)"
>
55
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#8CFFFFFF"
/>
56
</
ColorAnimationUsingKeyFrames
>
57
<
ColorAnimationUsingKeyFrames
Storyboard.TargetName
="BackgroundGradient"
Storyboard.TargetProperty
="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)"
>
58
<
SplineColorKeyFrame
KeyTime
="0"
Value
="#3FFFFFFF"
/>
59
</
ColorAnimationUsingKeyFrames
>
60
</
Storyboard
>
61
</
VisualState
>
62
<
VisualState
x:Name
="Disabled"
>
63
<
Storyboard
>
64
<
DoubleAnimationUsingKeyFrames
Storyboard.TargetName
="DisabledVisualElement"
Storyboard.TargetProperty
="Opacity"
>
65
<
SplineDoubleKeyFrame
KeyTime
="0"
Value
=".55"
/>
66
</
DoubleAnimationUsingKeyFrames
>
67
</
Storyboard
>
68
</
VisualState
>
69
</
VisualStateGroup
>
70
<
VisualStateGroup
x:Name
="FocusStates"
>
71
<
VisualState
x:Name
="Focused"
>
72
<
Storyboard
>
73
<
DoubleAnimationUsingKeyFrames
Storyboard.TargetName
="FocusVisualElement"
Storyboard.TargetProperty
="Opacity"
>
74
<
SplineDoubleKeyFrame
KeyTime
="0"
Value
="1"
/>
75
</
DoubleAnimationUsingKeyFrames
>
76
</
Storyboard
>
77
</
VisualState
>
78
<
VisualState
x:Name
="Unfocused"
/>
79
</
VisualStateGroup
>
80
</
VisualStateManager.VisualStateGroups
>
81
<
Border
x:Name
="Background"
Background
="White"
BorderBrush
="
{TemplateBinding BorderBrush}
"
BorderThickness
="
{TemplateBinding BorderThickness}
"
CornerRadius
="3"
>
82
<
Grid
Margin
="1"
Background
="
{TemplateBinding Background}
"
>
83
<
Border
x:Name
="BackgroundAnimation"
Opacity
="0"
Background
="#FF448DCA"
/>
84
<
Rectangle
x:Name
="BackgroundGradient"
>
85
<
Rectangle.Fill
>
86
<
LinearGradientBrush
EndPoint
=".7,1"
StartPoint
=".7,0"
>
87
<
GradientStop
Color
="#FFFFFFFF"
Offset
="0"
/>
88
<
GradientStop
Color
="#F9FFFFFF"
Offset
="0.375"
/>
89
<
GradientStop
Color
="#E5FFFFFF"
Offset
="0.625"
/>
90
<
GradientStop
Color
="#C6FFFFFF"
Offset
="1"
/>
91
</
LinearGradientBrush
>
92
</
Rectangle.Fill
>
93
</
Rectangle
>
94
</
Grid
>
95
</
Border
>
96
<
ContentPresenter
x:Name
="contentPresenter"
HorizontalAlignment
="
{TemplateBinding HorizontalContentAlignment}
"
Margin
="
{TemplateBinding Padding}
"
VerticalAlignment
="
{TemplateBinding VerticalContentAlignment}
"
Content
="
{TemplateBinding Content}
"
ContentTemplate
="
{TemplateBinding ContentTemplate}
"
/>
97
<
Rectangle
x:Name
="DisabledVisualElement"
Fill
="#FFFFFFFF"
RadiusX
="3"
RadiusY
="3"
IsHitTestVisible
="false"
Opacity
="0"
/>
98
<
Rectangle
x:Name
="FocusVisualElement"
Stroke
="#FF6DBDD1"
StrokeThickness
="1"
RadiusX
="2"
RadiusY
="2"
Margin
="1"
IsHitTestVisible
="false"
Opacity
="0"
/>
99
</
Grid
>
100
</
ControlTemplate
>
101
</
Setter.Value
>
102
</
Setter
>
103
</
Style
>
104
</
ResourceDictionary
>
下面咱們用一個簡單的實例來理解Style(樣式)和Template(模板)。
首先,咱們建立一個新的項目StyleTemplateDemo做爲演示。
打開MainPage,在主設計窗口中,添加三個按鈕控件到該頁面,
對於Button控件的
樣式屬性控制,最簡單的方法就是從右邊Properties屬性欄,
若是須要建立自定義樣式,則須要按照如下步驟:
首先選中其中一個按鈕控件,在左上角能夠看到Button控件下拉菜單,
點擊「[Button]」下拉菜單,選擇「Edit Template」,而後選擇「Edit a Copy」,
或者,能夠在主設計窗口,使用鼠標右鍵選中控件,選擇「Edit Template」,而後選擇「Edit a Copy」,
選中「Edit a Copy」,系統會彈出提示窗口,詢問「Create Style Resource」是否建立樣式資源,
其中Name(Key)是樣式名,之後調用該樣式將使用這個Name;
Define in 有三個選擇:
1. Application(應用),該選項是將該樣式代碼添加到App.Xaml文件中;
2. This document(當前文檔),該選項是將該樣式代碼添加到當前編輯文檔中,當前咱們編輯MainPage.Xaml,若是選中此項,樣式代碼將被輸出到該文件中;
3. Resource dictionary(資源目錄),該選項是將該樣式代碼添加到自定義資源文件中,若是沒有資源文件,能夠點擊「New」建立自定義資源文件;
在This document(當前文檔)中,該選項有兩個選擇,
「UserControl:<no name>」,選中該選項樣式代碼將在當前文檔建立<UserControl.Resources>,
調用是使用前面的基礎調用代碼:
1
<
Button
Margin
="114,197,0,228"
Width
="139"
Content
="Button"
HorizontalAlignment
="Left"
d:LayoutOverrides
="Width"
Style
="
{StaticResource ButtonStyle1}
"
/>
「Button:<no name>」,選中該選項樣式代碼將建立在該控件資源下,
對比以上三種定義樣式代碼方式,第一種和第三種方法相對來講比較靈活,將樣式代碼放在公共資源文件中,方便其餘頁面相同屬性控件調用;而第二種方法,僅供該文件中的相同屬性控件調用。
這裏咱們Define in選擇Application,定義樣式代碼到App.xaml中,點擊肯定後,系統會打開App.xaml文件,進入控件樣式編輯狀態,這時就能夠對控件樣式進行編輯。
當前主設計窗口打開文件爲"App.xaml",由於該文件包含了要編輯的樣式和模板代碼。
在控件處於樣式和模板編輯狀態下,從Objects and Timeline窗口能夠查看該控件模板的子部件,經過修改包含的子部件樣式,來改變原按鈕控件樣式。
例如咱們想改變Button的背景色,能夠修改BackgroundGradient屬性,從上圖的Objects and Timeline中選中BackgroundGradient,
在右邊Properties屬性欄,修改顏色,便可看到在主設計窗口按鈕的背景色在改變。
保存以上修改後,回到主設計窗口,能看到兩個Button已經被應用了新的Button樣式,
1
<
Grid
x:Name
="LayoutRoot"
Background
="White"
>
2
<
Button
x:Name
="bt1"
Margin
="254,151,247,0"
Width
="139"
Content
="按鈕樣式"
Style
="
{StaticResource ButtonStyle1}
"
Height
="55"
VerticalAlignment
="Top"
/>
3
<
Button
Margin
="0,151,92,0"
Width
="139"
Content
="Button"
HorizontalAlignment
="Right"
d:LayoutOverrides
="Width"
Height
="55"
VerticalAlignment
="Top"
/>
4
<
Button
Margin
="94,151,0,0"
Width
="139"
Content
="Button"
HorizontalAlignment
="Left"
d:LayoutOverrides
="Width"
Style
="
{StaticResource ButtonStyle1}
"
Height
="55"
VerticalAlignment
="Top"
/>
5
</
Grid
>
從代碼中能夠看出,使用
Style
="
{StaticResource ButtonStyle1}
" 的按鈕,已經將默認Button樣式替換爲新的Button樣式。若是想修改最後一個Button的樣式,一樣,把
Style
="
{StaticResource ButtonStyle1}
" 屬性添加到Button中便可。 在Blend中能夠很是簡單的應用新的樣式到控件。
在須要被應用樣式的Button控件上點擊鼠標右鍵,而後選擇「Edit Template」->「Apply Resource」 ->選中當前須要被應用的樣式,在主設計窗口便可看到控件樣式的變化。
如今,咱們切換左邊的Objects and Timeline 到 States,當前選中的States是CommonStates組中的Normal, 閱讀過上一篇VSM教程的,相信對這裏並不陌生,Normal表示Button控件的正常視圖狀態。
這裏咱們能夠看到,在主設計窗口,Button樣式仍舊是紫色
當咱們選中MouseOver視圖狀態時,主設計窗口Button樣式,變成默認的樣式。這說明,每一個Visual State視覺狀態都有本身獨立樣式,和上一篇講述的控件每一個視圖狀態都有獨立性是相符的。
因此,要修改完整的一套控件樣式,須要以控件的視圖狀態爲基礎,修改每一個會引發控件視圖產生變化的狀態。這裏,咱們選中MouseOver後,切換Tab到 Objects and Timeline,
選中「BackgroundGradient」,修改Button控件在鼠標覆蓋後的背景,
保存後,F5運行該例程,當鼠標放在Button上,自動會切換Button樣式。
Normal狀態:
MouseOver狀態:
Pressed狀態:
上圖能夠看出Pressed狀態並無改變,仍舊是默認樣式。其樣式修改方法與上面的方法相同,這裏再也不重複,你們能夠按照以上方法修改。
對於控件樣式的的控制,基本已經講完。在下一篇將介紹Template模板的應用實例。