Welcome to WindowsClient.net | Sign in | Join

Faisal's Blog

Sponsors





  • advertise here

Articles

Blogroll

Creating NikeClone With Silverlight Part-7

Introduction

Welcome to the part seven of NikeClone series. In the last part I showed you how to design the UItemplates UserControl. In this part I’ll explain the rest of the functionality of UITemplates and how they are implemented.

Starting The Implementation

So far our UI is looking something like the screen shot below:

UITemplatesFinishedIndesignMode

You can see in the above screen shot you can see that there’s a Menu at the left in the first column of the Grid and a TimelineUI(Which consists six buttons inside a StackPanel) which will change it’s state to pressed with the animated slide show of Images. Hare’s a screen shot of the TimelineUI when app is running:

TimelinrUIRunning

Here’s the two templates for these Buttons. One for Normal and the other for Pressed State.

Here’s the template form Normal State:

<ControlTemplate x:Key="TimelineButtonTemplate" 
 TargetType="Button">
<
Grid
>
<
vsm:VisualStateManager.VisualStateGroups
>
<
vsm:VisualStateGroup x:Name
="CommonStates">
<
vsm:VisualStateGroup.Transitions
>
<
vsm:VisualTransition GeneratedDuration
="00:00:00.3000000"/>
<
vsm:VisualTransition From="Normal" GeneratedDuration="00:00:00.3000000" To
="MouseOver"/>
<
vsm:VisualTransition From="MouseOver" GeneratedDuration="00:00:00.3000000" To
="Normal"/>
<
vsm:VisualTransition From="Pressed" GeneratedDuration="00:00:00.3000000" To
="Normal"/>
</
vsm:VisualStateGroup.Transitions
>
<
vsm:VisualState x:Name
="MouseOver">
<
Storyboard d:ShouldSerialize
="False"/>
</
vsm:VisualState
>
<
vsm:VisualState x:Name
="Normal"/>
<
vsm:VisualState x:Name
="Pressed">
<
Storyboard
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000" Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FFFFFFFF"/>
</
ColorAnimationUsingKeyFrames
>
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000" Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Offset)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="0.728"/>
</
DoubleAnimationUsingKeyFrames
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000" Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FF3F3F3F"/>
</
ColorAnimationUsingKeyFrames
>
<
PointAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.StartPoint)">
<
EasingPointKeyFrame KeyTime="00:00:00" Value
="0.532,-1.133"/>
</
PointAnimationUsingKeyFrames
>
<
PointAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.EndPoint)">
<
EasingPointKeyFrame KeyTime="00:00:00" Value
="0.529,1.778"/>
</
PointAnimationUsingKeyFrames
>
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000" Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="0.531"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard
>
</
vsm:VisualState
>
<
vsm:VisualState x:Name
="Disabled"/>
</
vsm:VisualStateGroup
>
<
vsm:VisualStateGroup x:Name
="FocusStates">
<
vsm:VisualState x:Name
="Unfocused"/>
<
vsm:VisualState x:Name
="Focused">
<
Storyboard d:ShouldSerialize
="False"/>
</
vsm:VisualState
>
</
vsm:VisualStateGroup
>
</
vsm:VisualStateManager.VisualStateGroups
>
<
Path x:Name="TimelineBG" Height="43" Stretch="Fill"
Data="F1 M 3.00003,364.744L 139.257,364.744C 140.913,364.744 142.257,
366.088 142.257,367.744L 142.257,404.744C 142.257,
406.401 140.913,407.744 139.257,407.744L 3.00003,407.744C 1.34319,
407.744 4.18673e-005,406.401 4.18673e-005,404.744L 4.18673e-005,
367.744C 4.18673e-005,366.088 1.34319,364.744 3.00003,364.744 Z " 
Margin="0,0,0,0" UseLayoutRounding="False" Width="144.2">
<
Path.Fill
>
<
LinearGradientBrush StartPoint="7.82502e-008,0.499998"
    EndPoint="1,0.499998">
<
GradientStop Color="#FF2E343A" Offset
="1"/>
<
GradientStop Color="#FF000000" Offset
="0"/>
<
GradientStop Color="#FFAFAFAF" Offset
="0.517"/>
</
LinearGradientBrush
>
</
Path.Fill
>
</
Path
>
<
Border Margin="0,0,0,0" BorderThickness="1,1,1,1" CornerRadius
="4,4,4,4">
<
Border.BorderBrush
>
<
LinearGradientBrush EndPoint="0.5,1" StartPoint
="0.5,0">
<
GradientStop Color
="#FF000000"/>
<
GradientStop Color="#FF000000" Offset
="1"/>
<
GradientStop Color="#FFFFFFFF" Offset
="0.53"/>
</
LinearGradientBrush
>
</
Border.BorderBrush
>
<
Grid
>
<
ContentPresenter Margin="0,0,0,0" HorizontalAlignment="Center"
VerticalAlignment="Center" Content="{TemplateBinding Content}"/>
</
Grid
>
</
Border
>
</
Grid
>
</
ControlTemplate>

 

Here the template for the Pressed State:

<ControlTemplate x:Key="TimelineSelectedButtonTemplate" TargetType="Button">
<
Grid
>
<
vsm:VisualStateManager.VisualStateGroups
>
<
vsm:VisualStateGroup x:Name
="CommonStates">
<
vsm:VisualStateGroup.Transitions
>
<
vsm:VisualTransition GeneratedDuration
="00:00:00.3000000"/>
<
vsm:VisualTransition From="Normal" GeneratedDuration="00:00:00.3000000"
 To="MouseOver"/>
<
vsm:VisualTransition From="MouseOver" GeneratedDuration="00:00:00.3000000"
 To="Normal"/>
<
vsm:VisualTransition From="Pressed" GeneratedDuration="00:00:00.3000000"
 To="Normal"/>
</
vsm:VisualStateGroup.Transitions
>
<
vsm:VisualState x:Name
="MouseOver">
<
Storyboard
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000" Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FF0E5EAF"/>
</
ColorAnimationUsingKeyFrames
>
</
Storyboard
>
</
vsm:VisualState
>
<
vsm:VisualState x:Name
="Normal">
<
Storyboard
>
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="0.513"/>
</
DoubleAnimationUsingKeyFrames
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FF000000"/>
</
ColorAnimationUsingKeyFrames
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FFFFFFFF"/>
</
ColorAnimationUsingKeyFrames
>
<
PointAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.EndPoint)">
<
EasingPointKeyFrame KeyTime="00:00:00" Value
="0.076,1.394"/>
</
PointAnimationUsingKeyFrames
>
<
PointAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.StartPoint)">
<
EasingPointKeyFrame KeyTime="00:00:00" Value
="0.071,-0.54"/>
</
PointAnimationUsingKeyFrames
>
</
Storyboard
>
</
vsm:VisualState
>
<
vsm:VisualState x:Name
="Pressed">
<
Storyboard
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000" Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FF4B4E51"/>
</
ColorAnimationUsingKeyFrames
>
</
Storyboard
>
</
vsm:VisualState
>
<
vsm:VisualState x:Name
="Disabled"/>
</
vsm:VisualStateGroup
>
<
vsm:VisualStateGroup x:Name
="FocusStates">
<
vsm:VisualState x:Name
="Unfocused"/>
<
vsm:VisualState x:Name
="Focused">
<
Storyboard
>
<
ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="TimelineBG" 
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<
EasingColorKeyFrame KeyTime="00:00:00" Value
="#FF103963"/>
</
ColorAnimationUsingKeyFrames
>
</
Storyboard
>
</
vsm:VisualState
>
</
vsm:VisualStateGroup
>
</
vsm:VisualStateManager.VisualStateGroups
>
<
Path x:Name="TimelineBG" Height="43" Stretch="Fill"
Data="F1 M 3.00003,364.744L 139.257,364.744C 140.913,364.744 142.257,
366.088 142.257,367.744L 142.257,404.744C 142.257,406.401 140.913,
407.744 139.257,407.744L 3.00003,407.744C 1.34319,407.744 4.18673e-005,
406.401 4.18673e-005,404.744L 4.18673e-005,367.744C 4.18673e-005,
366.088 1.34319,364.744 3.00003,364.744 Z " 
Margin="0,0,0,0" UseLayoutRounding="False" Width="144.2">
<
Path.Fill
>
<
LinearGradientBrush StartPoint="0.506,-1.247" EndPoint
="0.501,2.177">
<
GradientStop Color="#FF454545" Offset
="0.636"/>
<
GradientStop Color="#FF3F3F3F" Offset
="0.351"/>
<
GradientStop Color="#FFFFFFFF" Offset
="0.497"/>
</
LinearGradientBrush
>
</
Path.Fill
>
</
Path
>
<
Border Margin="0,0,0,0" BorderThickness="1,1,1,1" CornerRadius
="4,4,4,4">
<
Border.BorderBrush
>
<
LinearGradientBrush EndPoint="0.5,1" StartPoint
="0.5,0">
<
GradientStop Color
="#FF000000"/>
<
GradientStop Color="#FF000000" Offset
="1"/>
<
GradientStop Color="#FFFFFFFF" Offset
="0.53"/>
</
LinearGradientBrush
>
</
Border.BorderBrush
>
<
Grid
>
<
ContentPresenter Margin="0,0,0,0" HorizontalAlignment="Center"
VerticalAlignment="Center" Content="{TemplateBinding Content}"/>
</
Grid
>
</
Border
>
</
Grid
>
</
ControlTemplate>

We need to add an Image just behind the TimeLineUI. Source of this Image will be changed at a specified interval. Select the LayoutRoot in the Objects and Timeline panel and add an Image. Name the Image imgMain. RightClick over the Image and change the Order by selecting Order->Send to Back.

Switching To The Code Behind

Switch to the UITemplates.xaml.cs to add some procedural code. Add these three namspaces:

using System.Windows.Media.Imaging;
using System.Windows.Threading;
using System.Collections.ObjectModel;

Declare some private member variables. At first create a new instance of DispatcherTimer by declaring something like the code below:

private DispatcherTimer timer = newDispatcherTimer();

Now declare an ObservableCollection of string somehing like this:

private ObservableCollection<string> _images=
new ObservableCollection<string>();

Declare another variable to set the default value of index:

private int _currentIndex = 0;

Now create a Method named SetImageSource which takes a parameter of string to pass the name of the image:

private void SetImageSource(string imageName)
{
string name = "Images/" + imageName;
BitmapImage bmi = new BitmapImage(new Uri(name, UriKind.Relative));
imgMain.Source = bmi;
}

Write another method to initialize images for the slide show and call the SetImageSource method from this method:

private void InitializeImages()
{

_images.Add("1.jpg");
_images.Add("2.jpg");
_images.Add("3.jpg");
_images.Add("4.jpg");
_images.Add("5.jpg");
_images.Add("6.jpg");
SetImageSource(_images[_currentIndex]);
}

You can see in the method above that SetImageSource method has been called from this method and the _images which is a ObservableCollection of string has been passed as its argument. Also the index has been set by passing the _currentIndex .

Creating SetStates Method For State Switching

We now need to write a method where the logic for changing the states of the buttons which has been placed inside TimelineUI(StackPanel with six Buttons). Here it is:

private void SetStates()
{

switch(_currentIndex)
{
case 0:

VisualStateManager.GoToState(this.btnTimeline1,"Pressed",true);
VisualStateManager.GoToState(this.btnTimeline2,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline3,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline4,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline5,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline6,"Normal",true);
break;
case 1 :
VisualStateManager.GoToState(this.btnTimeline2,"Pressed",true);
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline3,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline4,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline5,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline6,"Normal",true);
break;
case 2 :
VisualStateManager.GoToState(this.btnTimeline3,"Pressed",true);
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline2,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline4,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline5,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline6,"Normal",true);
break;
case 3 :
VisualStateManager.GoToState(this.btnTimeline4,"Pressed",true);
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline2,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline3,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline5,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline6,"Normal",true);
break;
case 4:
VisualStateManager.GoToState(this.btnTimeline5,"Pressed",true);
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline3,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline4,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline6,"Normal",true);
break;
case 5 :
VisualStateManager.GoToState(this.btnTimeline6,"Pressed",true);
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline2,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline3,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline4,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline5,"Normal",true);
break;
default :
VisualStateManager.GoToState(this.btnTimeline1,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline2,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline3,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline4,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline5,"Normal",true);
VisualStateManager.GoToState(this.btnTimeline6,"Normal",true);
break;
}
}

Define The Animation for SlideShow

Switch to the Xaml View in Blend and Add these two animation inside the <UserControl.Resources></UserControl.Resources> section by pasting the following Xaml:

<Storyboard x:Name="FadeOutAnimation" 
Completed="FadeOutAnimation_Completed">
<
DoubleAnimation Duration="00:00:00.50" From="5" To="0"
Storyboard.TargetProperty="Opacity" Storyboard.TargetName="imgMain" />
</
Storyboard
>
 <Storyboard x:Name="FadeInAnimation">
<
DoubleAnimation Duration="00:00:00.50" From="0" To="5"
Storyboard.TargetProperty="Opacity" Storyboard.TargetName="imgMain" />
</
Storyboard>

The Above two Storyboards are for fade in and out of images. Note that the above two animations has different From and To value. For the Completed event of the FadeOutAnimation add the code below:

void FadeOutAnimation_Completed(object sender, EventArgs e)
{
SetImageSource(_images[_currentIndex]);
FadeInAnimation.Begin();
}

Adding Tick EventHandler

Switch to the code behind and add a Tick event for the Dispatcher by pasting the following code:

private void dispatcher_Tick(object sender,EventArgs e)
{
_currentIndex++;

if (_currentIndex == _images.Count)
{
_currentIndex= 0;

}
SetStates();
FadeOutAnimation.Begin();

}

SetStates() method and the Begin method of FadeOutAnimation has been called inside this event. Switch to the Xaml View in Blend and select the UITemplates and then in the Properties panel switch to the events view and write StartTimer in the Loaded textbox.

UITemplatesEventsView

Double click over the StartTimer text. This will take you to the code behind in blend and also add a StartTimer Routed event. Here’s that event:

public void StartTimer(object sender, RoutedEventArgs e)
{
InitializeImages();
timer.Interval = TimeSpan.FromSeconds(4);
timer.Tick+=new EventHandler(dispatcher_Tick);
timer.Start();
}

Inside this Routed event I’ve called the IntializeImages() method and then set the interval of DispatcherTimer, Attach the Tick event of DispatcherTimer and at last called the Start() method to start the animation. Now run the app to test the Animation. You should see something like the screen shots below :

Slide1 Slide2

 

Slide3 Slide4

Slide5 Slide6

Adding Animation For The ExpandableMenu

Create a new Storyboard by clicking over the + sign in the Objects and Timeline panel:

Creating New Storyboard In Blend

Name the Storyboard sbExpMenu. Select ExpandableMenu in the Objects and Timeline panel. Drag the playhead position to 5 seconds. In the properties panel set the Height of the ExpandableMenu to 270. Create another Storyboard by following the same process. Name the Storyboard sbExpMenuCollapsed. Select Expandablemenu in the Objects and Timeline panel and drag the playhead position to 5 seconds. Set the Height of the ExpandableMenu to 0. Drag back the playhead position to 0 secons and set the Height to 270 in the properties panel. Close the Storyboard and select btnItemExpander. Switch to the Events view in the properties panel and just after the Click textbox write the name of your button’s click method. Name it btnItemExpander_Click and double click over it to switch to the code behind.

btnItemExpanderClickEvent

Here’s the code for the btnItemExpander Click event:

private void btnItemExpander_Click(object sender, System.Windows.RoutedEventArgs e)
{

if(expandableMenu.Height==0)
{
expandableMenu.Height=270;
sbExpMenu.Begin();
sbMenuTop.Begin();
}
else
{
sbExpMenuCollapsed.Begin();
sbCloseMenuTop.Begin();
}
}

Here I have set a condition with if statement to expand and collapse the ExpandableMenu. First I checked out whether the Height of the ExpandableMenu. if it is 0 then I set a condition to set it to 270 and  then called the Begin() method of sbExpMenu and sbMenuTop Storyboard(ou’ll know soon about sbMenuTop). Otherwise I called the sbExpMenuCollapsed Storyboard’s Begin() method and SbCloseMenuTop’s Begin() method to collapse the ExpandableMenu and the HyperlinkButton over it which is ExpandableMenu’s header(btnMenuHeader).

The Idea is if I click over the btnItemExpander both btnMenuHeader and ExpandableMenu will expand their size. Clicking over the btnItemExpander again will collapse both of them.

Here’s sbMenuTop Storyboard settings in Blend:

sbMenuTopInBlend

You can see in the above screen shot that the plathead position is at 2 seconds and the Width of the btnMenuHeader is 174. Here’s the Xaml :

<Storyboard x:Name="sbMenuTop">
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="btnmenuHeader" 
Storyboard.TargetProperty="(FrameworkElement.Width)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="0"/>
<
SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="175"
KeySpline="0,0.430999994277954,1,1"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard>

Here’s the settings for sbCloseMenuTop Storyboard:

sbCloseMenuTop

Again in the above screen shot the playhead position lastly at 2 seconds but this time the Width hase been set to 0 and when you drag the playhead position to 0, you’ll be able to see the Width 175 in the properties panel. That means It’ll do the opposite of sbMenuTop and help us to collapse the btnMenuHeader. Here’s the Xaml:

<Storyboard x:Name="sbCloseMenuTop">
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="btnmenuHeader" 
Storyboard.TargetProperty="(FrameworkElement.Width)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="175"/>
<
EasingDoubleKeyFrame KeyTime="00:00:00.2000000" Value
="0"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard>

At this point we have finished adding Animation functionality for our ExpandableMenu.

Adding Animation For The StyledSearchTextBox

To implement animation functionality for our StyledSearchTextBox we need to add two more Storyboards. I’m not going into details of how to create Storyboards this time. I’m assuming so far you’ve learnt a lot about Storybaords.

So just paste the Xaml in the <UserControl.Resources> </UserControl.Resources> section of the UITemplates UserControl :

<Storyboard x:Name="sbStyledSearch">
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="styledSearchTextBox" 
Storyboard.TargetProperty="(FrameworkElement.Width)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="0"/>
<
EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value
="291"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard>

<
Storyboard x:Name="sbStyledSearchCollapsed">
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="styledSearchTextBox" 
Storyboard.TargetProperty="(FrameworkElement.Width)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="291"/>
<
EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value
="0"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard>

Select btnFrontSearch and switch to the Events view in the properties panel to define Click event for the btnFrontSearch. Here’s the Event:

private void btnfrontSearch_Click(object sender, 
System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
if (btnBackSearch.Visibility == Visibility.Collapsed)
{
btnBackSearch.Visibility = Visibility.Visible;
btnfrontSearch.Visibility = Visibility.Collapsed;
sbStyledSearch.Begin();
}
else
{
btnBackSearch.Visibility = Visibility.Collapsed;
}
}

In the above event handler first I checked out whether btnBackSearch’s Visible property is Collapsed or not. If it Collapsed then I set a condition to make it Visible and ser the btnFrontSearch’s Visibility property to Collapsed and after this I called sbStyledSearch Storyboard’s Begin() method. Otherwise btnBackSearch’s property will be Collapsed.

Again the idea here is similar like the ExpandableMenu. Where we set a condition inside click event to expand and collapse the btnMenuHeader and ExpandableMenu. For this case I’ve played a little with the Visibility property of both the btnFrontSearch and btnBackSearch. Cause they were placed in the same position of the LayoutRoot(Grid) and Only one of them were visible. By default btnBackSearch was not Visible. The idea here is when I click over the btnFrontSearch the btnBackSearch will become visible and btnFrontSearch will be out of the view with its property turned into Collapsed at Run time. Also The StyledSearchTextBox will be animated to increase it’s Width. By clicking over the btnBackSearch(Which will be visible after clicking over the btnFrontSearch) we can bring the btnFrontSearch again into view and decrease the Width of the StyledSearchTextBox to make it invisible again.

Adding Animation For The StpTimeline

StpTimeline is a StackPanel we added for the six Buttons which will change it’s state to Pressed automatically with slide show. Here we’re going to add two storyboards for making it visible and invisible on MouseEnter and MouseLeave to give our application a nice effect.

Paste the following Xaml in the <UserControl.Resources></UserControl.Resources> section of the UITemplates UserControl:

<Storyboard x:Name="sbTimeline">
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="stpTimeline" 
Storyboard.TargetProperty="(FrameworkElement.Height)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="0"/>
<
EasingDoubleKeyFrame KeyTime="00:00:00.4000000" Value
="27"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard
>
<Storyboard x:Name="sbTimeline2">
<
DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="stpTimeline" 
Storyboard.TargetProperty="(FrameworkElement.Height)">
<
EasingDoubleKeyFrame KeyTime="00:00:00" Value
="27"/>
<
EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value
="0"/>
</
DoubleAnimationUsingKeyFrames
>
</
Storyboard>

The first Storyboard which is sbTimeline changes the Height to 0 when playhead position of the Storyboard is in 0 second and when when playhead position is in 4 seconds the Height has been set to 27 . In the second Storyboard which is sbTimeline2 when the playhead position is at 0 the Heisght has been set to 27 and when it is in 4 seconds height has been set to 0.

Adding MouseEnter And MouseLeave Event

In the objects and Timeline panel select imgMain :

imgMain

In the properties panel switch to the Events view and define a MouseEnter event for imgMain:

imgMainMouseEnterEventInBlend

Double click over imgMain_MouseEnter to switch to the code behind. Add this code for the MouseEnter event of the imgMain:

private void imgMain_MouseEnter(object sender, 
System.Windows.Input.MouseEventArgs e)
{

if(stpTimeline.Height==0)
{
stpTimeline.Height=27;
sbTimeline.Begin();
}

}

Logic is really simple for this event. If height is 0 then I set it to 27 and called the Begin() method of sbTimeline Storyboard.

Select the CardsUI in the Objects and Timeline panel  and define the MouseLeft event by following the previous process. Here’s the code:

private void cardUI_MouseLeave(object sender, 
System.Windows.Input.MouseEventArgs e)
{
if(stpTimeline.Height==27)
{
stpTimeline.Height=0;
sbTimeline2.Begin();
}
}

For the MouseLeave I set a condition if Height is 27 then it’ll turn into 0 and called the sbTimeline2 storyboards Begin() method. At this point our NikeClone journey is finished.

After debugging the app you’ll be now able to see something like this:

NikeCloneFinished

If you take your mouse over the the CardsUI area of the page It will change it’s state:

NikeCloneFinished2

And Clicking over a specific Image will help you to see it in the entire area of the CardsUI:

NikeCloneFinished3

If you click over the Button with Nike logo at the top left you’ll be able to see this :

NikeCloneFinished4

By clicking over the Search Button you experience this :

NikeCloneFinished5

By clicking over the Menu’s you’ll experience something like this:

NikeCloneFinished6

And clicking over the Login Button will bring up the LoginWindow:

NikeCloneFinished7

Conclusion

This was just an effort to check out what Silverlight can do for us. I was really satisfied with the result though this is not a complete app by any mean but I have a plan to implement more functionality. Hope you’ve enjoyed this journey of NikeClone. Happy coding and Happy Silverlight.

Shout it
Posted: Jul 09 2009, 12:18 PM by ilves | with 1 comment(s)
Filed under:

Comments

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout

# July 9, 2009 2:26 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Page view counter