Windows phone 7之樣式與模板

就像網頁配合CSS一樣,XAML元素結合Style可以使Silverlight頁面變得絢麗多彩。Silverlight的最大吸引力就是無論你想做什麼格式的,什麼效果的頁面你都可以實現,絕對沒有不可能。想使頁面變得絢麗,簡單Style就可以,想使頁面變得特性十足或是千變萬化,那就學好模板,想要使頁面動起來,Storyboard可以幫助你。
樣式(Style)、模板(Template)很少直接定義在控件或者頁面元素內部,一般都定義在外部資源文件中,這樣不但便於維護,更便於重用。什麼叫資源,凡是放在頁面或控件Resource節點下,或是放在獨立資源文件中的ResourceDictionary節點下的全是資源,Style和Template都屬於資源。
將Style定義在App.xaml文件中,看下面的代碼

  1. <Application

  2. x:Class="StyleAndTemplate.App"

  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  5. xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

  6. xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">
  7. <!--Application Resources-->

  8. <Application.Resources>

  9. <Style x:Key="MyTextBlock" TargetType="TextBlock">

  10. <Setter Property="FontSize" Value="50"/>

  11. <Setter Property="Foreground" Value="Blue"/>

  12. </Style>

  13. </Application.Resources>
  14. <Application.ApplicationLifetimeObjects>

  15. <!--Required object that handles lifetime events for the application-->

  16. <shell:PhoneApplicationService

  17. Launching="Application_Launching" Closing="Application_Closing"

  18. Activated="Application_Activated" Deactivated="Application_Deactivated"/>

  19. </Application.ApplicationLifetimeObjects>
  20. </Application>
複製代碼
如上面的代碼,只要將Style寫在Application.Resources節點下
將Style定義在單獨的資源文件中,首先需要在項目中添加一個xaml後綴的文件(MyResource.xaml),在文件中寫入如下代碼

  1. <ResourceDictionary

  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  4. xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

  5. xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">



  6. <Style x:Key="MyTextBlock" TargetType="TextBlock">

  7. <Setter Property="FontSize" Value="50"/>

  8. <Setter Property="Foreground" Value="Blue"/>

  9. </Style>

  10. </ResourceDictionary>
複製代碼
看上面的文件,ResourceDictionary節點寫添加i幾個命名空間,前三個是必須的,第一個字默認命名空間,資源的象徵,第二個用來定義唯一標示,沒有他,無法定義和引用資源,第三個是引入控件,用於填入TargetType屬性(下面說明他的重要性)。定義好了資源文件還需要在App.xaml文件中註冊該資源文件,在App.xaml中寫入如下代碼

  1. <Application.Resources>

  2. <ResourceDictionary>

  3. <ResourceDictionary.MergedDictionaries>

  4. <ResourceDictionary Source="MyResource.xaml"/>

  5. </ResourceDictionary.MergedDictionaries>

  6. </ResourceDictionary>

  7. </Application.Resources>
複製代碼
這樣在頁面中,就可以使用該Style了,MainPage.xaml中添加一個TextBlock,並給他添加樣式,寫法:<TextBlock Text="MyText" Style="{StaticResource MyTextBlock}"/>,StaticResource是靜態資源的標示,所有定義在頁面級、App.xaml中或者定義在外部資源中的都是靜態資源,還有一個RelativeSource,是定義在某元素內部時,父子控件之間相互使用的資源,沒人使用,不用研究。
上述兩種方式運行效果是一樣的,如下圖所示
31-1 20120417083711704.jpg
2012-5-2 18:15:52 上傳
下載附件 (8.91 KB)


樣式(Sytle)
Style主要包含兩種屬性和一個子節點
x:Key屬性是Style的唯一標示,必須有且不能重複,爲控件設置Style時使用,格式Style="{StaticResource Key}"
TargetType屬性,該屬性標示Style應用於何種控件,所有Style只用應用於一種控件,並不是所有的資源都是這樣,比如SolidColorBrush,可以用於任何控件的顏色屬性。這個屬性也是必須有的,加入上面說的第三個命名空間,就可使在文件中使用WP7的基礎弓箭了,這樣輸入TargetType時就會自動提示,如果那個命名空間,就不能使用WP7基礎控件,所以填入內容使也會報錯,這就是他必要的原因,如果使用Toolkit,只要將應用添加項目中,並在資源文件中加以命名空間就行了。
<Setter>子節點,有人說這也是Style的一個屬性,我不反對,但是他的確是只能以子節點的方式使用。
Setter可是設置控件個任何屬性,也就是一個控件可是完全由Style定製。Setter有兩個屬性,Property,用來填入屬性名,Value,用來填入屬性值,也就是說一個Setter設置一個屬性。
上述說的三個屬性時Style的必須屬性,缺一不可,x:Key是所有資源的必須屬性。
不但可以使用Style爲控件定義樣式,一些任何控件都具有的屬性可以放在Resource根節點下,而不必放在Style的Setter中,比如SolidColorBrush可以設置顏色、FontFamily可以設置字體,他們不放在Style中。
樣式是具有優先級的,如果設置使用Style和屬性設置重複後,只有一個起作用,那麼誰起作用呢,一般分三個等級,1、默認樣式,沒有爲控件設置任何樣式,則使用默認樣式,2、Style設置的樣式,設置Style後將覆蓋默認樣式,3、屬性中直接設置,這種方式優先級最高,他優先起作用。
至於Style都可以設置哪些屬性,在TargetType之後,在你寫Setter時,會有自動提示,只有找到自己想要的就行了。
簡單說一下模板(Template)
模板有很多種,我只說兩種萬能模板,其他的,童鞋們自己體會吧,都是一樣的。什麼是萬能模板,就是可以應用到任何可以使用模板的控件上
DataTemplate
這個模板可以說是萬能的,可以用來設置控件的內容(ContentTemplate),也可以設置佈局(ItemTemplate),下面以Button爲例說一下他的用法
在資源中定義一個DataTemplate

  1. <DataTemplate x:Key="DataKey">

  2. <StackPanel>

  3. <TextBlock Text="Templage"/>

  4. <TextBlock Text="I'm a Template"/>

  5. </StackPanel>

  6. </DataTemplate>
複製代碼
在頁面中放置一個Button:
<Button Margin="10,120,0,0" VerticalAlignment="Top" Width="259" ContentTemplate="{StaticResource DataKey}">
運行效果如下
31-2 20120417083711827.jpg
2012-5-2 18:15:52 上傳
下載附件 (13.58 KB)



看到模板的作用了嗎,這就是我之前說的爲什麼silverlight是變化無窮的,因爲你可以用一個模板將空間做成任何你想要的樣子
ControlTemplate
ControlTemplate一般用Gid開定義控件的佈局,用VisualState控制狀態,一般是動畫,ContentControl用來顯示Content
我們爲了簡單,從Blend複製一個Button的完整Style

  1. <Style x:Key="MyButtonStyle" TargetType="Button">

  2. <Setter Property="Background" Value="Transparent"/>

  3. <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>

  4. <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>

  5. <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>

  6. <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>

  7. <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>

  8. <Setter Property="Padding" Value="10,3,10,5"/>

  9. <Setter Property="Template">

  10. <Setter.Value>

  11. <ControlTemplate TargetType="Button">

  12. <Grid Background="Transparent">

  13. <VisualStateManager.VisualStateGroups>

  14. <VisualStateGroup x:Name="CommonStates">

  15. <VisualState x:Name="Normal"/>

  16. <VisualState x:Name="MouseOver"/>

  17. <VisualState x:Name="Pressed">

  18. <Storyboard>


  19. <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
  20. Storyboard.TargetName="ContentContainer">

  21. <DiscreteObjectKeyFrame
  22. KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>

  23. </ObjectAnimationUsingKeyFrames>


  24. <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"
  25. Storyboard.TargetName="ButtonBackground">

  26. <DiscreteObjectKeyFrame
  27. KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>

  28. </ObjectAnimationUsingKeyFrames>


  29. <ObjectAnimationUsingKeyFrames
  30. Storyboard.TargetProperty="BorderBrush"
  31. Storyboard.TargetName="ButtonBackground">

  32. <DiscreteObjectKeyFrame
  33. KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>

  34. </ObjectAnimationUsingKeyFrames>

  35. </Storyboard>

  36. </VisualState>

  37. <VisualState x:Name="Disabled">

  38. <Storyboard>


  39. <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
  40. Storyboard.TargetName="ContentContainer">

  41. <DiscreteObjectKeyFrame
  42. KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

  43. </ObjectAnimationUsingKeyFrames>


  44. <ObjectAnimationUsingKeyFrames
  45. Storyboard.TargetProperty="BorderBrush"
  46. Storyboard.TargetName="ButtonBackground">

  47. <DiscreteObjectKeyFrame
  48. KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

  49. </ObjectAnimationUsingKeyFrames>


  50. <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"
  51. Storyboard.TargetName="ButtonBackground">

  52. <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>

  53. </ObjectAnimationUsingKeyFrames>

  54. </Storyboard>

  55. </VisualState>

  56. </VisualStateGroup>

  57. </VisualStateManager.VisualStateGroups>

  58. <Border x:Name="ButtonBackground"
  59. BorderBrush="{TemplateBinding BorderBrush}"
  60. BorderThickness="{TemplateBinding BorderThickness}"
  61. Background="{TemplateBinding Background}" CornerRadius="0"
  62. Margin="{StaticResource PhoneTouchTargetOverhang}">

  63. <ContentControl x:Name="ContentContainer"
  64. ContentTemplate="{TemplateBinding ContentTemplate}"
  65. Content="{TemplateBinding Content}" Foreground="{TemplateBinding
  66. Foreground}" HorizontalContentAlignment="{TemplateBinding
  67. HorizontalContentAlignment}" Padding="{TemplateBinding Padding}"
  68. VerticalContentAlignment="{TemplateBinding
  69. VerticalContentAlignment}"/>

  70. </Border>

  71. </Grid>

  72. </ControlTemplate>

  73. </Setter.Value>

  74. </Setter>

  75. </Style>
複製代碼
這是系統默認的Button樣式,我沒設置控件的樣式時,可以修改系統默認的樣式,這樣效率更高些
我們看到Style中包含一個ControlTemplate,VisualState設置了點擊時的樣式和禁用時的樣式,加上默認的樣式,默認Button按鈕有三種形態,現在我改變Pressed的狀態動畫,改變背景色爲Red,將這個Style設置給一個Button

  1. <VisualState x:Name="Pressed">

  2. <Storyboard>


  3. <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
  4. Storyboard.TargetName="ContentContainer">

  5. <DiscreteObjectKeyFrame
  6. KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>

  7. </ObjectAnimationUsingKeyFrames>


  8. <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"
  9. Storyboard.TargetName="ButtonBackground">

  10. <DiscreteObjectKeyFrame KeyTime="0" Value="Red"/>

  11. </ObjectAnimationUsingKeyFrames>


  12. <ObjectAnimationUsingKeyFrames
  13. Storyboard.TargetProperty="BorderBrush"
  14. Storyboard.TargetName="ButtonBackground">

  15. <DiscreteObjectKeyFrame
  16. KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>

  17. </ObjectAnimationUsingKeyFrames>

  18. </Storyboard>

  19. </VisualState>
複製代碼
運行程序,點擊Content爲button的按鈕,效果如下
31-3 20120417083712608.jpg
2012-5-2 18:15:51 上傳
下載附件 (18.6 KB)





上面我簡單的改變了一下Pressed狀態的動畫,如果你想得到更加豐富的效果,可以自己定製。
ContentControl是用來顯示內用的控件,所有繼承自ContentControl的控件模板中都有這個屬性,沒有就無法顯示內容了,只剩個空模板了。
在給初學者說一下TemplateBinding,他是用來綁定屬性的,如ContentControl中的Content="{TemplateBinding Content}",意思是ContentControl的Content屬性顯示的是控件的Content屬性的值,也就是Button的值"button"。他跟Binding不一樣,Binding是綁定的數據,如一個對象中的屬性。Person.Name,後面章節馬上介紹Binding,童鞋們別急。

大家如果認爲我寫的內容有用的話就幫頂一下,點一下推薦,你們的支持就是我的動力!!!先謝謝了!!!
想看比較深入的技術的童鞋別急,因爲我這基礎篇已經寫了三分之二了,我儘量在五篇左右將之結束,然後進入開發技巧章節,給他家分享使用的開發技術。

作者 董賀超

http://hlu019001.chinaw3.com/thread-2381-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章