Creating a Button
Style at Runtime in Silverlight 3
In this post, I will show how to apply a style at runtime to
a button.
Creating the style:
You can create the style by two ways. If you are good in
xaml coding then you can create it in Visual Studio. The simple one is to
create a sample project in expression blend and use the "Edit Template" feature
o create the style.
How To?
While
creating the button style in expression blend you need to be careful with the
options.
The
Name(key) option is the key given to the style. Internally the framework link
the styles with this key. It will be unique per one application or user control
depending what you choose in the "define in" option. If you choose the "this
document " option then the style will be available only in the current user
control. If you want to use the style to your whole project, then select the
"Application" option. For this post I will choose Application.
The Style:
<Application.Resources>
<Style
x:Key="ButtonStyle1" TargetType="Button">
<Setter
Property="Background" Value="#FF1F3B53"/>
<Setter
Property="Foreground" Value="#FF000000"/>
<Setter
Property="Padding" Value="3"/>
<Setter
Property="BorderThickness" Value="1"/>
<Setter
Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush
EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop
Color="#FFA3AEB9" Offset="0"/>
<GradientStop
Color="#FF8399A9" Offset="0.375"/>
<GradientStop
Color="#FF718597" Offset="0.375"/>
<GradientStop
Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup
x:Name="CommonStates">
<VisualState
x:Name="Normal"/>
<VisualState
x:Name="MouseOver">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundAnimation"
Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame
KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#F2FFFFFF"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#CCFFFFFF"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#7FFFFFFF"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState
x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Background"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#FF6DBDD1"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundAnimation"
Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame
KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#D8FFFFFF"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#C6FFFFFF"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#8CFFFFFF"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
<SplineColorKeyFrame
KeyTime="0" Value="#3FFFFFFF"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState
x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup
x:Name="FocusStates">
<VisualState
x:Name="Focused">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="FocusVisualElement"
Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame
KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState
x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
x:Name="Background" Background="White"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Grid
Margin="1" Background="{TemplateBinding Background}">
<Border
x:Name="BackgroundAnimation" Opacity="0"
Background="#FF448DCA"/>
<Rectangle
x:Name="BackgroundGradient">
<Rectangle.Fill>
<LinearGradientBrush
EndPoint=".7,1" StartPoint=".7,0">
<GradientStop
Color="#FFFFFFFF" Offset="0"/>
<GradientStop
Color="#F9FFFFFF" Offset="0.375"/>
<GradientStop
Color="#E5FFFFFF" Offset="0.625"/>
<GradientStop
Color="#C6FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Border>
<Rectangle
x:Name="FocusVisualElement" Stroke="#FF6DBDD1"
StrokeThickness="1" RadiusX="2" RadiusY="2" Margin="1"
IsHitTestVisible="false" Opacity="0"/>
<Image
Source="Excel.png" Stretch="Fill"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
If you go
through this xaml, you will see the style is created under
Application.Resources and ready to be used for any .xaml file in the project.
Applying in runtime:
There are
two ways of applying this style. If you are creating a button compile time,
then in the xaml you can apply the style like this :
<Button
x:Name="btnSubmit" Style="{StaticResources ButtonStyle1}"/>
But if you
have to create a button runtime and want to have the same look and feel then
this approach is not worth. I saw my team mate creating the button then making
its visibility as collapsed and then in the code making it visible. But that is
not the correct procedure. You can do something like this:
Button btn = new Button();
btn.Style = Application.Current.Resources["ButtonStyle1"] as
Style;
btn.HorizontalAlignment = HorizontalAlignment.Left;
LayoutRoot.Children.Add(btn);
Here you can use the style from the
Application.Current.Resources which is a dictionary. J. Then adding it to the correct parent. I am adding to the LayOutRoot
here.
Thanks.