最近在用Silverligh做一個網絡文件管理程序,但用在設計界面的時候覺得Silverligh默認的button樣式太大眾化了,所以就產生了自己定義按鈕樣式的念頭.在網絡一找的確有很多這方面的文章,但都有一個問題就是只定義了按鈕的默認狀態的樣式.對於mouseover等基本都沒有的.還好后來在msdn里找到詳細幫助描述.以下就詳細講述Silverligh中定義一個按鈕各種狀態的樣式.
在定義按鈕模板前先看下需要的效果

通過上面的圖需要給按鈕制定4種狀態:不可用,默認,鼠標移上去,鼠標點下.
先定義不可用圖層
<Rectangle x:Name="DisabledVisualElement" RadiusX="1" RadiusY="1" Fill="#5A7C7777" Opacity="0" IsHitTestVisible="false" ></Rectangle>
可以根據你需要的顏色會制一個距形,把IsHitTestVisible設置成false
定義默認狀態的圖層
<Rectangle Opacity="0" x:Name="default" RadiusY="1" RadiusX="1" Stroke="Gray" Fill="#C7E8E8E8"></Rectangle>
和不可用圖層一樣緩制一個距形即可,當然當然自己的需要制定邊框和填充顏色
定義鼠標移上去效果
<Rectangle Opacity="0" x:Name="over" RadiusY="1" RadiusX="1" Stroke="#FF2458FF">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#C70DA0FC" Offset="1" />
<GradientStop Color="#C9FFFFFF" Offset="0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
同樣也是會制一個距形,只是填充上是一個色階.
最后就是定義鼠標按下去的效果
<Rectangle Opacity="0" x:Name="mouseDown" RadiusY="1" RadiusX="1" Stroke="#FF858683">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#C980E5FF" Offset="1" />
<GradientStop Color="#C8FFFFFF" Offset="0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
其實和鼠標移上去的一樣,只是色階顏色有差別
不同狀態的圖層都已經制作完成,下面的工作就是在不同狀態下對這幾個圖層進行設置.Silverligh提供VisualStateManager來定義控件在每種狀態下效果制定.按鈕分別提供了Disabled,Normal,MouseOver和Pressed.
Disabled
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="ctlitem" Storyboard.TargetProperty="(UIElement.Opacity)" To="0.5"/>
<DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="(UIElement.Opacity)" To=".55"/>
</Storyboard>
</VisualState>
第一個效果把控件里的內容設置一個秀明度為0.5,這樣做的目的是讓按鈕中的圖片看起來有點蒙的效果.
第二個效果就是把不可用圖層顯示出來.
Normal
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="default" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
把默認狀態的圖層顯示出來
MouseOver
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="over" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
顯示鼠標移進效果
Pressed
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="mouseDown" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
顯示鼠標按下去效果
看完以上代碼相信很多朋友都應該明白,其實就是在不同狀態下用運動效果來改變某個圖層的顯示情況來達到不同狀態效果.
下面是整個按鈕模板的代碼
<Style x:Key="toolbaritem" TargetType="Button">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Margin" Value="2,2,0,2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="ctlitem" Storyboard.TargetProperty="(UIElement.Opacity)" To="0.5"/>
<DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="(UIElement.Opacity)" To=".55"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="default" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="over" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="mouseDown" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Opacity="0" x:Name="over" RadiusY="1" RadiusX="1" Stroke="#FF2458FF">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#C70DA0FC" Offset="1" />
<GradientStop Color="#C9FFFFFF" Offset="0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Opacity="0" x:Name="mouseDown" RadiusY="1" RadiusX="1" Stroke="#FF858683">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#C980E5FF" Offset="1" />
<GradientStop Color="#C8FFFFFF" Offset="0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Opacity="0" x:Name="default" RadiusY="1" RadiusX="1" Stroke="Gray" Fill="#C7E8E8E8"></Rectangle>
<ContentControl Margin="4" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="ContentControlChild" >
<ContentPresenter Name="ctlitem" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ContentControl>
<Rectangle x:Name="DisabledVisualElement" RadiusX="1" RadiusY="1" Fill="#5A7C7777" Opacity="0" IsHitTestVisible="false" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
