Silverlight 样式的灵活使用
众所周知,Silverlight将界面设计与代码实现分开。即便如此,如果不能灵活地运用样式Style,开发的效率依然会比较低。比如,针对类似的TextBlock,你可能需要反复地在设计器xaml中复制粘贴很多行设计器代码。但如果开发人员掌握了样式的使用,可以一次设计,到处使用。
(一)获取一个控件的样式Style文件
这里以FloatableWindow控件为例
(1)打开一个继承自FloatableWindow的控件OverlapControl的设计器文件OverlapControl.xaml,在菜单栏中点击”视图->在Blend中打开“(View->Open in Blend),如下如所示
(2)打开Blend之后,在Object and Timeline视图中,右键"FloatableWindow",并选择“Edit Template->Create Empty”,创建新一个新的资源字典ResourceDictionary.xaml:
(3)假如该控件没有与任何ResourceDictionary文件关联,则需要新建一个资源字典文件ResourceDictionary:
(4)修改资源字典文件的名称,点击“确定”(OK),如此,就可以在当前目录看到创建的资源字典文件FloatableWindowStyle.xaml
此时,在OverlapControl.xaml设计器文件中,会多上几行引用的代码:
(二)调整或设置控件的样式Style文件
此时,重新再Blend中打开OverlapControl.xaml或者打开FloatableWindowStyle.xaml,可以对FloatableWindow的样式进行调整,或者设置其对应的参数:
(1)打开编辑样式资源的开关:
(2)随后,在视图区中,可以看到FloatableWindow的简单视图:
(3)选中“属性”(Properties)选项卡,可以非常方便地设置该控件的参数:
(4)当然,开发人员也可以在设计器文件中直接调整参数的值,一下代码本人调整好后的代码:
1 <ResourceDictionary 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:windows="clr-namespace:System.Windows.Controls;assembly=FloatableWindow"> 4 <!-- Resource dictionary entries should be defined here. --> 5 <LinearGradientBrush x:Key="HeaderBackgroundBrush" EndPoint="0,0" StartPoint="0,1"> 6 <GradientStop Offset="0.0" Color="#92bfbe"/> 7 <GradientStop Offset="0.2" Color="#8dc5c4"/> 8 <GradientStop Offset="0.8" Color="#8dc5c4"/> 9 <GradientStop Offset="1.0" Color="#92bfbe"/> 10 </LinearGradientBrush> 11 12 <SolidColorBrush x:Key="HeaderBorderBrush" Color="#ff9bb6b5" /> 13 14 <Style x:Key="FloatableWindowStyle1" TargetType="windows:FloatableWindow"> 15 16 17 <Setter Property="IsTabStop" Value="false"/> 18 <Setter Property="TabNavigation" Value="Cycle"/> 19 <Setter Property="HorizontalAlignment" Value="Center"/> 20 <Setter Property="VerticalAlignment" Value="Center"/> 21 <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 22 <Setter Property="VerticalContentAlignment" Value="Stretch"/> 23 <Setter Property="BorderThickness" Value="1"/> 24 <Setter Property="BorderBrush"> 25 <Setter.Value> 26 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 27 <GradientStop Color="#FFA3AEB9" Offset="0"/> 28 <GradientStop Color="#FF8399A9" Offset="0.375"/> 29 <GradientStop Color="#FF718597" Offset="0.375"/> 30 <GradientStop Color="#FF617584" Offset="1"/> 31 </LinearGradientBrush> 32 </Setter.Value> 33 </Setter> 34 <Setter Property="OverlayBrush" Value="#7F000000"/> 35 <Setter Property="OverlayOpacity" Value="1"/> 36 <Setter Property="Template"> 37 <Setter.Value> 38 <ControlTemplate TargetType="windows:FloatableWindow"> 39 <Grid x:Name="Root"> 40 <Grid.Resources> 41 <Style x:Key="ButtonStyle" TargetType="Button"> 42 <Setter Property="Background" Value="#FF1F3B53"/> 43 <Setter Property="Foreground" Value="#FF000000"/> 44 <Setter Property="Padding" Value="3"/> 45 <Setter Property="BorderThickness" Value="1"/> 46 <Setter Property="BorderBrush"> 47 <Setter.Value> 48 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 49 <GradientStop Color="#FFA3AEB9" Offset="0"/> 50 <GradientStop Color="#FF8399A9" Offset="0.375"/> 51 <GradientStop Color="#FF718597" Offset="0.375"/> 52 <GradientStop Color="#FF617584" Offset="1"/> 53 </LinearGradientBrush> 54 </Setter.Value> 55 </Setter> 56 <Setter Property="Template"> 57 <Setter.Value> 58 <ControlTemplate TargetType="Button"> 59 <Grid x:Name="grid" Background="#02FFFFFF" HorizontalAlignment="Center" Height="14" VerticalAlignment="Center" Width="15"> 60 <VisualStateManager.VisualStateGroups> 61 <VisualStateGroup x:Name="CommonStates"> 62 <VisualState x:Name="Normal"/> 63 <VisualState x:Name="MouseOver"> 64 <Storyboard> 65 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="X_Fuzz2"> 66 <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 67 </ObjectAnimationUsingKeyFrames> 68 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="X_Fuzz1"> 69 <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 70 </ObjectAnimationUsingKeyFrames> 71 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="X_Fuzz0"> 72 <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 73 </ObjectAnimationUsingKeyFrames> 74 <DoubleAnimation Duration="0" To="0.95" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="X"/> 75 </Storyboard> 76 </VisualState> 77 <VisualState x:Name="Pressed"> 78 <Storyboard> 79 <DoubleAnimation Duration="0" To="0.85" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="X"/> 80 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="X_Fuzz2"> 81 <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 82 </ObjectAnimationUsingKeyFrames> 83 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="X_Fuzz1"> 84 <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 85 </ObjectAnimationUsingKeyFrames> 86 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="X_Fuzz0"> 87 <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 88 </ObjectAnimationUsingKeyFrames> 89 </Storyboard> 90 </VisualState> 91 <VisualState x:Name="Disabled"> 92 <Storyboard> 93 <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="X"/> 94 </Storyboard> 95 </VisualState> 96 </VisualStateGroup> 97 </VisualStateManager.VisualStateGroups> 98 <Path x:Name="X_Fuzz2" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" Fill="#14C51900" HorizontalAlignment="Center" Height="8" Margin="0,-1,0,0" Opacity="1" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#14C51900" Visibility="Collapsed" VerticalAlignment="Center" Width="9"> 99 <Path.RenderTransform> 100 <TransformGroup> 101 <ScaleTransform ScaleY="1.3" ScaleX="1.3"/> 102 </TransformGroup> 103 </Path.RenderTransform> 104 </Path> 105 <Path x:Name="X_Fuzz1" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" Fill="#1EC51900" HorizontalAlignment="Center" Height="8" Margin="0,-1,0,0" Opacity="1" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#1EC51900" Visibility="Collapsed" VerticalAlignment="Center" Width="9"> 106 <Path.RenderTransform> 107 <TransformGroup> 108 <ScaleTransform ScaleY="1.1" ScaleX="1.1"/> 109 </TransformGroup> 110 </Path.RenderTransform> 111 </Path> 112 <Path x:Name="X_Fuzz0" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" Fill="#FFC51900" HorizontalAlignment="Center" Height="8" Margin="0,-1,0,0" Opacity="1" Stretch="Fill" Stroke="#FFC51900" Visibility="Collapsed" VerticalAlignment="Center" Width="9"/> 113 <Path x:Name="X" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" Fill="#FFFFFFFF" HorizontalAlignment="Center" Height="8" Margin="0,-1,0,0" Opacity="0.7" Stretch="Fill" VerticalAlignment="Center" Width="9"> 114 <Path.Stroke> 115 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 116 <GradientStop Color="#FF313131" Offset="1"/> 117 <GradientStop Color="#FF8E9092" Offset="0"/> 118 </LinearGradientBrush> 119 </Path.Stroke> 120 </Path> 121 </Grid> 122 </ControlTemplate> 123 </Setter.Value> 124 </Setter> 125 </Style> 126 </Grid.Resources> 127 <VisualStateManager.VisualStateGroups> 128 <VisualStateGroup x:Name="WindowStates"> 129 <VisualState x:Name="Open"> 130 <Storyboard> 131 <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Overlay"> 132 <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 133 <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="1"/> 134 </DoubleAnimationUsingKeyFrames> 135 <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX" Storyboard.TargetName="ContentRoot"> 136 <SplineDoubleKeyFrame KeyTime="0" Value="0"/> 137 <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0"/> 138 <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1"/> 139 <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" KeyTime="00:00:00.45" Value="1.05"/> 140 <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1"/> 141 </DoubleAnimationUsingKeyFrames> 142 <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY" Storyboard.TargetName="ContentRoot"> 143 <SplineDoubleKeyFrame KeyTime="0" Value="0"/> 144 <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0"/> 145 <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1"/> 146 <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" KeyTime="00:00:00.45" Value="1.05"/> 147 <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1"/> 148 </DoubleAnimationUsingKeyFrames> 149 </Storyboard> 150 </VisualState> 151 <VisualState x:Name="Closed"> 152 <Storyboard> 153 <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Overlay"> 154 <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 155 <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="0"/> 156 </DoubleAnimationUsingKeyFrames> 157 <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX" Storyboard.TargetName="ContentRoot"> 158 <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1"/> 159 <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05"/> 160 <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0"/> 161 </DoubleAnimationUsingKeyFrames> 162 <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY" Storyboard.TargetName="ContentRoot"> 163 <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1"/> 164 <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05"/> 165 <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0"/> 166 </DoubleAnimationUsingKeyFrames> 167 </Storyboard> 168 </VisualState> 169 </VisualStateGroup> 170 </VisualStateManager.VisualStateGroups> 171 <Grid x:Name="Overlay" Background="{TemplateBinding OverlayBrush}" HorizontalAlignment="Stretch" Margin="0" Opacity="{TemplateBinding OverlayOpacity}" VerticalAlignment="Top"/> 172 <Grid x:Name="ContentRoot" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Height="{TemplateBinding Height}" RenderTransformOrigin="0.5,0.5" 173 VerticalAlignment="{TemplateBinding VerticalAlignment}" Width="{TemplateBinding Width}"> 174 <Grid.RenderTransform> 175 <TransformGroup> 176 <ScaleTransform/> 177 <SkewTransform/> 178 <RotateTransform/> 179 <TranslateTransform/> 180 </TransformGroup> 181 </Grid.RenderTransform> 182 183 <Border BorderBrush="#14000000" BorderThickness="1" Background="#14000000" CornerRadius="2" HorizontalAlignment="Stretch" Margin="-1" VerticalAlignment="Stretch"/> 184 <Border BorderBrush="#0F000000" BorderThickness="1" Background="#0F000000" CornerRadius="2.25" HorizontalAlignment="Stretch" Margin="-2" VerticalAlignment="Stretch"/> 185 <Border BorderBrush="#0C000000" BorderThickness="1" Background="#0C000000" CornerRadius="2.5" HorizontalAlignment="Stretch" Margin="-3" VerticalAlignment="Stretch"/> 186 <Border BorderBrush="#0A000000" BorderThickness="1" Background="#0A000000" CornerRadius="2.75" HorizontalAlignment="Stretch" Margin="-4" VerticalAlignment="Stretch"/> 187 188 <!--*********************************整个面板的边框***********************************--> 189 <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="#FFFFFFFF" CornerRadius="5"> 190 <Border CornerRadius="1.5" Margin="0"> 191 <Border.Background><!--面板背景色--> 192 <!-- 193 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 194 <GradientStop Color="#FFE5E8EB" Offset="1"/> 195 <GradientStop Color="#FFF6F8F9" Offset="0"/> 196 </LinearGradientBrush> 197 --> 198 <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> 199 <GradientStop Offset="0" Color="#FFffffff"/> 200 <GradientStop Offset="1.0" Color="#FFffffff"/> 201 </LinearGradientBrush> 202 </Border.Background> 203 <Grid> 204 <Grid.RowDefinitions> 205 <RowDefinition Height="Auto"/> 206 <RowDefinition/> 207 </Grid.RowDefinitions> 208 209 <!--*********************************标题框……边框***********************************--> 210 <Border x:Name="Chrome" BorderBrush="{StaticResource HeaderBorderBrush}" BorderThickness="1,1,1,1" Width="Auto" Background="{StaticResource HeaderBackgroundBrush}"> 211 212 <Grid Height="Auto" Width="Auto"> 213 <Grid.ColumnDefinitions> 214 <ColumnDefinition/> 215 <ColumnDefinition Width="30"/> 216 </Grid.ColumnDefinitions> 217 218 <!--******************************************************标题***************************************--> 219 <ContentControl Content="{TemplateBinding Title}" FontWeight="Bold" HorizontalAlignment="Stretch" IsTabStop="False" 220 Margin="6,3,6,3" VerticalAlignment="Center"/> 221 222 <!--******************************************************关闭按钮***************************************--> 223 <Button x:Name="CloseButton" Grid.Column="1" HorizontalAlignment="Center" Height="14" IsTabStop="False" Cursor="Hand" 224 Style="{StaticResource ButtonStyle}" VerticalAlignment="Center" Width="15"/> 225 </Grid> 226 </Border> 227 228 <!--******************************************************主要内容区域***************************************--> 229 <Border Background="{TemplateBinding Background}" Margin="7" Grid.Row="1"> 230 <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 231 </Border> 232 <!--******************************************************右下角 的透明三角形,控制伸缩***************************************--> 233 <Path x:Name="Resizer" Data="M15.499995,0.5 L15.499995,15.5 L0.5,15.5 z" Fill="#FFB1B1B1" 234 HorizontalAlignment="Right" Height="20" Opacity=".25" Grid.Row="1" Stretch="Fill" UseLayoutRounding="False" 235 VerticalAlignment="Bottom" Width="20"/> 236 </Grid> 237 </Border> 238 </Border> 239 </Grid> 240 </Grid> 241 </ControlTemplate> 242 </Setter.Value> 243 </Setter> 244 </Style> 245 </ResourceDictionary>
(5)简单地介绍一下如何设置一个控件的样式Style
首先设置一个标签<Style ></Style>,并设置一个x:Key,以作为引用的依据,并设置目标空间类型:TargetType。
利用如下的语句可以设置属性类型和属性值:
<Setter Property="HorizontalContentAlignment" Value="Center"/>
通过自己的观察,可以研究其他类型的样式设计,比如色刷、渐变色等。
(三)引用控件的样式Style或样式文件
在“(一)(4)”中已经提到了资源字典文件ResourceDictionary的引用。此类文件,其实也是一种资源,与图片等资源的引用有些类似。
(1)比如,你在某一个工程下面设置了一个资源字典文件DropDownMenu.xaml,假如要在整个解决方案solution中引用,可以在App.xaml中做如下的引用
(2)如果开发者想在某一个控件中引用一个样式,可参考如下语句:
<TextBlock x:Name="tbkNews" Style="{StaticResource menuTextBlockStyle}" MouseLeftButtonDown="tbkNews_MouseLeftButtonDown">
(3)如果给某一个窗口控件定义了样式,可参照如下的样式引用:
<controls:ChildWindow.Style> <StaticResource ResourceKey="ChildWindowStyle"/> </controls:ChildWindow.Style>
小结一下,Silverlight支持界面的灵活设计,其与底层逻辑剥离,比较容易实现。同时资源字典文件和样式的使用可以大大提高已有界面的重用行,进而提高开发效率。而要获取某一个空间的资源文件,Blend会是一个很好的工具。所以,将Blend与资源字典文件结合使用,一定可以大大丰富界面,提升开发的进度。