Welcome to WindowsClient.net | My Blog | Sign in | Join

Faisal's Blog

March 2008 - Posts

Creating reflection with Silverlight 2.0 beta

I was searching for some WPF videos, after googling I found a site named contentpresenter . I found couple of interesting video there on WPF. After releasing of Silverlight 2.0 beta , my intention is implementing those WPF stuff in Silverlight as much as possible cause they're quite similar now. Let's start how I did this.

I found a video at contentpresenter on reflection. The idea behind this is video running on media element will be reflected. Much like mirror effect we've seen created in photoshop. Reflection will exactly be the reverse of original video which will be reflected on a rectangle located just beneath the media element. I have done that by changing XAML a little bit and the job was done. Here's my XAML step by step:

Inside my root Grid I have set both the Horizontal and Vertical alignment to center. This will center anything inside this Grid.Fixed it's width to 800 and height to 640 something like this :

<Grid x:Name="LayoutRoot" HorizontalAlignment="Center" 
  VerticalAlignment="Center" Width="800" Height="640" 
  MouseLeftButtonDown="TopElement_OnFullScreenChaged">

</
Grid>
 
After this I've Open Expression Blend 2.5 March 2008 Preview to Fill 
the background of my grid named LayoutRoot. Here's screen shot :
grid background 
 
Note that Under the interaction panel(Objects and Timeline) which is in this case
LayOutRoot name of my root grid has been selected to fix the Background color. I've
selected LinearGradientBrush to change the Background of my grid and this created the
following XAML :
<Grid.Background>
<
LinearGradientBrush EndPoint="0.493999987840652,1"
                    StartPoint="0.505999982357025,0">
<
GradientStop Color="#FF000000"/>
<
GradientStop Color="#FFA29C9C" Offset="1"/>
</
LinearGradientBrush>
</Grid.Background>

 

Next I've used StackPanel to have my Video top of the StackPanel and the reflection of the video bottom of the StackPanel.In the first section of the stack panel is the Border to add some border around MediaElement, you can also use the Grid .

Inside this Border I've placed my MediaElement. The MediaElement which i've named mElement is selected under the properties panel selecting the media tab and changing the source property has set the source of the video. Here's the Screen Shot :

 

media element Source

 

MediaElement is now inside the border. To absolutely size the media element I've set the width and height of the border to 328 and 248.I've fixed the background of my Broder to LinearGraidient.To stretching all the way through the border I've fixed the horizontal and vertical alignment to stretch.To bring in each side to 4 pixels I've set margin to 4 pixels to have that border.

Stretched Horizontal and Vertical Alignment

 

Now it's time to paint the actual video file to Rectangle. At first I have set the fill property of the Rectangle to fix the Background. This going to serve as reflection.

I've just set the Rectangle.Fill property to VideoBrush and set it's SourceName property to the the Border grdVideo that contains the media element. Now we can have perfect copy of the video playing beneath the original video painted over a Rectangle. But it's not the reflection of the video because it's actually needs to be flipped on the Y axes.To do that we can use transform property of the VideoBrush.

First it has been scaled on Y axes and then translated so I needed to use TransformGroup to allow multiple transform. Under the <TransformGroup> tag I've used the ScaleTransform and set it's ScaleY to negative 1. This flips on the Y axes.

To translate to the Y axes I've set the TranslateTransform Y property equal to our Border's height which is 248.Here's the screen shot on full screen mode :

Reflection FullScreen

 

This looks good but this is bit too strong cause in reflection opacity is much lighter and fades out towards the bottom. To achieve this I've played a bit with the opacity mask of the Rectangle. I've used the Gradient Brush for the opacity masks. First i've selected the right color key of the gradient and set it's alpha value to 0 and Left  color key somewhere round 30. I've used the gradient transform tool change the direction of the gradient by holding shift key for the perfection.Below is the screen shot after this modifications:

 

 

RealisticReflection

 

Now it's much more realistic. You can add video of your choice and play with the gradient background,Rectangle opacity mask etc. as much as you like to make it more realistic. Here's my XAML after all of this :

<UserControl x:Class="SilverlightReflection.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Height="640" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" OpacityMask="#FF000000" >


<
Grid x:Name="LayoutRoot" HorizontalAlignment="Center" VerticalAlignment="Center" Width="800" Height="640" MouseLeftButtonDown="TopElement_OnFullScreenChaged">
<
Grid.Background>
<
LinearGradientBrush EndPoint="0.474999994039536,0.523000001907349" StartPoint="0.47299998998642,0.181999996304512">
<
GradientStop Color="#FF8E8C8C"/>
<
GradientStop Color="#E9928F8F" Offset="0.8880000114440918"/>
<
GradientStop Color="#FFA4A4A4" Offset="0.656"/>
<
GradientStop Color="#FF6D6B6B" Offset="0.451"/>
<
GradientStop Color="#FF7E7C7C" Offset="0.21899999678134918"/>
</
LinearGradientBrush>
</
Grid.Background>
<
StackPanel Margin="0,0,0,0">
<
Border x:Name="grdVideo" Width="328" Height="248" MouseLeftButtonDown="grid_MouseLeftButtonDown">
<
Border.Background>
<
LinearGradientBrush EndPoint="0.5,1" StartPoint="0.493999987840652,1.79799997806549">
<
GradientStop Color="#FF000000"/>
<
GradientStop Color="#FF686565" Offset="1"/>
</
LinearGradientBrush>
</
Border.Background>
<
MediaElement x:Name="mElement" Source="Media/sl1.wmv" Margin="4,4,4,4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<
MediaElement.OpacityMask>
<
LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<
GradientStop Color="#FF000000"/>
<
GradientStop Color="#FF878383" Offset="1"/>
</
LinearGradientBrush>
</
MediaElement.OpacityMask>
</
MediaElement>
</
Border>
<
Rectangle x:Name="recVideo" Width="328" Height="248" Margin="4,1,4,1" StrokeThickness="4" RenderTransformOrigin="0.5,0.5">
<
Rectangle.OpacityMask>
<
LinearGradientBrush EndPoint="0.50900000333786,0.83899998664856" StartPoint="0.5,-0.208000004291534">
<
GradientStop Color="#4D000000"/>
<
GradientStop Color="#00FFFFFF" Offset="1"/>
</
LinearGradientBrush>
</
Rectangle.OpacityMask>
<
Rectangle.Fill>
<
VideoBrush SourceName="mElement">
<
VideoBrush.Transform>
<
TransformGroup>
<
ScaleTransform ScaleY="-1"/>
<
TranslateTransform Y="248"/>
</
TransformGroup>
</
VideoBrush.Transform>
</
VideoBrush>
</
Rectangle.Fill>

</
Rectangle>
</
StackPanel>

</
Grid>
</
UserControl>

To wire some event and get this in Full Screen I've added something in my Page.xaml.cs section which is quite simple and shown below  :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightReflection
{
public partial class Page : UserControl
{
private SilverlightHost slHost = new SilverlightHost();

public Page()
{
InitializeComponent();
}

private void TopElement_OnFullScreenChaged(object sender,
                                                   EventArgs e)
{
SizeUI();
}

private void SizeUI()
{
grdVideo.Width = this.ActualWidth/2;
grdVideo.Height =this.ActualHeight/2;
recVideo.Width = grdVideo.Width;
recVideo.Height = grdVideo.Height;
}

private void grid_MouseLeftButtonDown(object sender,
                                             MouseEventArgs e)
{
if (slHost.Content.IsFullScreen)
{
slHost.Content.IsFullScreen = false;
}
else
{
slHost.Content.IsFullScreen = true;
}
}
}
}

 

That's all . Expecting your opinion and  suggestion to do much better than this.

Happy coding.

kick it on DotNetKicks.com
Posted: Mar 24 2008, 08:48 PM by ilves | with 15 comment(s)
Filed under:
Changing the visual appearance of the control with Silverlight 2 Beta

Now Silverlight has become quite similar to WPF, it's become easier to change the visual appearance of the controls.With the beta 2 release of Silverlight we've found rich set of controls now to work with.In this demonstration of changing appearance of the controls,I just tried to apply what I learnt from WPF.Those useful styling and Templating of controls by using Style and ControlTemplate.

There's two classes that assist us in specifying the appearance of our controls in fact our applications are Style and ControlTemplate. By setting Property values of style we can apply the style to multiple instances of a control.Each control uses the property value that we set in the Style.To change the appearance beyond  setting Control's properties,we can create ControlTemplate which defines the appearance and visual behavior of a control. Element that inherits from FrameworkElement can have a style  applied to it.Elements that inherit from the Control have a ControlTemplate.

 

The Style class defined in System.Windows.The most important property of style is named Setters.The Setters property is of type SetterBaseCollection, which is a collection of SetterBase objects.Setter is the content property of Style.Setter basically associates a particular property with a value,and the two crucial properties of the Setter class are property of type Dependency property and Value of type object.The following Xaml syntax uses Setter property of Style to fix the Background of a Button and Foreground of a TextBlock :

              

<UserControl.Resources>
       <Style TargetType="Button" x:Key="MyButtonStyle">
<
Setter Property="Background" Value="Maroon"></Setter>
</
Style>

<
Style TargetType="TextBlock" x:Key="MyTextBlockStyle">
<
Setter Property="Foreground" Value="Blue"></Setter>
</
Style>
</UserControl.Resources>

Now apply this to our Button and TextBlock like the following Xaml.

    <Grid>   
<
Button Width="86" Height="55" Style="{StaticResource MyButtonStyle}" >
<
TextBlock Width="76" Height="55" Text="My Button" Style="{StaticResource MyTextBlockStyle}"></TextBlock>
</
Button>
</
Grid>
 

Here's the screen shot of the styled control :

MyButton

You can also change the FontSize ,FontStyle to your like.Just set the property and it's value to the Style section to your linking.x:key attribute uniquely identifies elements that are created and referenced as resources and which exist within a ResourceDictionary which provides a dictionary that contains keyed resources used by components of a Silverlight based application.Each resource property element within each ResourceDictionary must have a unique value for the x:key,which servers as the uniqe key when values are retrieved from the ResourceDictionary.

Notice that I've defined the style in the UserControl's resources section to apply the styles here to all the Button's and TextBlock's.By defining styles in resources section they can be shared among multiple elements and controls.Styles defined in the Resources section of the Application object can be used throughout the application.The Resources property of application gets a collection of resources like Styles,Templates and Brushes.The value of the Resources property contains the ResourceDictionary that is set from XAML by using the Application.Resources property element.These resources can be used to support multiple themes across an application.The example below shows a style named myStyle for a Button and brush style for a TextBlock's Foreground which is defined as an application-scoped resource which can be shared across multiple UIs.

 

<Application xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Silverlight2InAction.App"
>
<
Application.Resources>
<
Style x:Key="myStyle" TargetType="Button">
<
Setter Property="Template">
<
Setter.Value>
<
ControlTemplate TargetType="Button">
<
Grid Margin="3">
<
Rectangle x:Name="backGlow" Fill="#FFEE08" RadiusX="10" RadiusY="10"/>
<
Rectangle x:Name="backDark" RadiusX="10" RadiusY="10">
<
Rectangle.Fill>
<
RadialGradientBrush GradientOrigin="0.9,0.9">
<
GradientStop Color="Black" Offset="0"/>
<
GradientStop Color="Black" Offset="0.60"/>
<
GradientStop Color="Transparent" Offset="0.2"/>
</
RadialGradientBrush>
</
Rectangle.Fill>
</
Rectangle>
<
Rectangle x:Name="mainButton" Fill="DarkBlue" Opacity="0.75"
RadiusX="10" RadiusY="10"/>
<
Rectangle x:Name="mainButtonBorder" Stroke="SteelBlue"
StrokeThickness="2" RadiusX="10" RadiusY="10"/>
<
ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
</
ContentPresenter>
<
Rectangle x:Name="buttonTopShine" Grid.ColumnSpan="3"
RadiusX="10" RadiusY="10">
<
Rectangle.Fill>
<
LinearGradientBrush StartPoint="0,0" EndPoint="0,1" Opacity="0.8">
<
GradientStop Color="White" Offset="0"/>
<
GradientStop Color="Transparent" Offset="0.3"/>
</
LinearGradientBrush>
</
Rectangle.Fill>
</
Rectangle>
<
Rectangle x:Name="buttonholers" Opacity="0" RadiusX="10" RadiusY="10">
<
Rectangle.Fill>
<
LinearGradientBrush>
<
GradientStop Color="White" Offset="0"/>
<
GradientStop Color="White" Offset="0.1"/>
<
GradientStop Color="Transparent" Offset="0.6"/>
</
LinearGradientBrush>
</
Rectangle.Fill>
</
Rectangle>
</
Grid>
</
ControlTemplate>
</
Setter.Value>
</
Setter>
</
Style>
<
Style x:Key="brushStyle" TargetType="TextBlock">
<
Setter Property="Foreground">
<
Setter.Value>
<
LinearGradientBrush>
<
GradientStop Color="LightBlue" Offset="0"></GradientStop>
<
GradientStop Color="SteelBlue" Offset="1"></GradientStop>
</
LinearGradientBrush>
</
Setter.Value>
</
Setter>
</
Style>
</
Application.Resources>
</
Application>

 

 

In the above Xaml two styles created one for Button which defined as myStyle and another one is brushStyle to change the Foreground of TextBlock.The Foreground of the TextBlock has been styled by specifying which property we want to stylize.Here assigned setter Property as Foreground.The Button's look is based on ControlTemplate.The shape of the button has been customized by creating rounded Rectangle.The ControlTemplate has a Button as it's target type.Since i need multiple things I constructed ControlTemplate to hold a Grid layout and have the Grid layout hold multiple children.Inside the Grid I've created a rounded rectangle to accomplish the glow with a bright yellow Color.The next Rectangle I created for dark effect by using RadialGradient by setting it's start to black and then to transparent.To get a slightly bigger area I used two gradient stops as Black at first before the gradient drops off.To put it towards the bottom right corner I've set the origin to 0.9 and 0.9.The next rectangle is named mainButton.To see the glow of the dark highlights behind it I tried to make this transculent by setting it's opacity to 0.75 .for the button border I created the next Rectangle named mainButtonBorder here I set the stroke to SteelBlue to get the desired border color of my Button.After this I defined Rectangle named buttonTopShine for the shining gradient effect on the top.You can play with the GradientStops of this which has been set to White and Transparent to see the effect.It makes the nice glow at the top of the button. It's a rounded rectangle with a gradient, the gradient is linear.The last one is buttonHoverGlow which I created for hovering effect.Below is the Xaml to set the Style on the desired Control.

<Grid> 
<
Button Style="{StaticResource myStyle}" Width="300" Height="175"
 MouseEnter="Button_MouseEnter" x:Name="button" ></Button>
<
TextBlock Text="My Styled Button" TextAlignment="Center" FontSize="25"
Style="{StaticResource brushStyle}" Width="280" Height="140"
Margin="190,90,200,0" FontStyle="Italic">
</
TextBlock>
</
Grid>

MyStyledButton

 

To get some hovering effect I've used Expression Blend 2.5 March 2008 Preview.

I've just set the opacity of the button by creating a new Storyboard and marked on the timeline to reduce the opacity from 100 to 76.

ExpressionBlend

 

This settings of timeline created an Xaml in the UserControl.Resources section like the following :

<UserControl.Resources>   
<
Storyboard x:Name="Storyboard1">
<
DoubleAnimationUsingKeyFrames Storyboard.TargetName="button" Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
<
SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.985"/>
<
SplineDoubleKeyFrame KeyTime="00:00:01" Value="0.755"/>
</
DoubleAnimationUsingKeyFrames>
</
Storyboard>
</
UserControl.Resources>

To wire the event's of the button I've just called the Storyboard's begin method in the Button's MouseEnter event.

void Button_MouseEnter(object sender, MouseEventArgs e)
{
Storyboard1.Begin();
}

Now let's run the application and see what happens.

AfterEntering

 

After entering the mouse over the button I got the result something shown above.

This was my first experience after releasing of Silverlight 2.0 Beta.I've just started to learn Silverlight.Hope you've enjoyed and I'm expecting suggestion and comments to give my best in my next post.

Thanks.

kick it on DotNetKicks.com
Posted: Mar 15 2008, 08:33 AM by ilves | with 3 comment(s)
Filed under:
Page view counter