Silverlight 3D: Using Plane Projection

In this article, we will see how to use 3D Plane Projection in Silverlight. For this demonstration I am using the following controls – 1) Border 2) DataGrid 3) Chart control from Silverlight toolkit and 4) Hyperlink button.
I am also using two story boards for creating a ‘Double Animation’.

So the first step is to create a Silverlight project. I am fond of Microsoft Expression Blend, although I am not a good designer :) Anyways, once you create a Silverlight project, add a class with the name ‘CustomerSales’ and add few properties to the same class as shown below –

customer sales

In this demonstration I am showing some sales records for different cities. Once you click the row, the total sales for Q1, Q2, Q3 and Q4 is shown in a chart format with some nice animation using Silverlight Plane Projection.

Now let’s import two namespaces in our sample as shown below –

image

Now go to your MainPage.xaml and replace <Grid></Grid> with the code shown below –

<UserControl.Resources>
<Storyboard x:Name="salesDGRowSelected">
    <DoubleAnimation Duration="0:0:3" To="-50"
        Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)"
        Storyboard.TargetName="dgAllSales" d:IsOptimized="True"/>
    <DoubleAnimation Duration="0:0:3" To="0"
        Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)"
         Storyboard.TargetName="border" d:IsOptimized="True"/>
    <DoubleAnimation Duration="0:0:3" To="1"
        Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border"
        d:IsOptimized="True"/>
    <DoubleAnimation Duration="0:0:3" To="-30"
        Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)"
        Storyboard.TargetName="border" d:IsOptimized="True"/>
</Storyboard>
<Storyboard x:Name="closeButtonClicked">
    <DoubleAnimation Duration="0:0:3" To="0"
        Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)"
        Storyboard.TargetName="dgAllSales" d:IsOptimized="True"/>
    <DoubleAnimation Duration="0:0:3" To="-30"
        Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)"
        Storyboard.TargetName="border" d:IsOptimized="True"/>
    <DoubleAnimation Duration="0:0:3" To="0"
        Storyboard.TargetProperty="(UIElement.Opacity)"
        Storyboard.TargetName="border" d:IsOptimized="True"/>
    <DoubleAnimation Duration="0:0:3" To="0"
        Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)"
        Storyboard.TargetName="border" d:IsOptimized="True"/>
</Storyboard>
</UserControl.Resources>


<Grid x:Name="LayoutRoot" Background="White">
        <sdk:DataGrid x:Name="dgAllSales" Margin="118,144,213,106"
        SelectionChanged="dgAllSales_SelectionChanged" Width="307" >
            <sdk:DataGrid.Projection>
                <PlaneProjection/>
            </sdk:DataGrid.Projection>
        </sdk:DataGrid>
        <Border x:Name="border" BorderBrush="Black" BorderThickness="1"
        Margin="119,144,214,106" Width="307" Height="180" CornerRadius="10" Opacity="0">
            <Border.Projection>
                <PlaneProjection RotationX="50"/>
            </Border.Projection>
            <Border.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF8C9796" Offset="0"/>
                    <GradientStop Color="#FF6CE4DB" Offset="1"/>
                </LinearGradientBrush>
            </Border.Background>
        <StackPanel Orientation="Vertical">
        <toolkit:Chart x:Name="salesColumnSeriesChart" Visibility="Visible">
                <toolkit:Chart.Series>
                <toolkit:ColumnSeries x:Name="MyColumnSeries" ItemsSource="{Binding}"
                    DependentValuePath="Value"
                    IndependentValuePath="Key"
                    Title="Sales" IsSelectionEnabled="True" />
                </toolkit:Chart.Series>
               </toolkit:Chart>
        <HyperlinkButton x:Name="closeButton" Content="Close The Graph !!"
        HorizontalAlignment="Right" Height="15" Margin="0,0,40,106"
        VerticalAlignment="Bottom" Width="93" BorderThickness="0" Click="closeButton_Click"/>
        </StackPanel>
        </Border>
       
</Grid>


Observe the above code. It contains a DataGrid control. It also contains a border in which we are using a stack panel. This stack panel contains a chart control and a Hyperlink button.

The above code also contains two story boards –

1) SalesDGRowSelected.
2) CloseButtonClicked.

First an animation will run when we click the row of the DataGrid and the second animation runs when we click the close button which is available in our border control.

Now let’s add code in our MainPage.xaml.cs file –

In the constructor, let’s call ‘this.Loaded’ event of the user control and write a code in the Loaded function as shown below –

image

In the above method, we are adding a sample data in a collection of ‘CustomerSales’ class and setting that collection as a source of the data to our DataGrid. Now, when we click the row of the DataGrid, we will read the complete row and set the values Q1, Q2, Q3, and Q4 column to out chart.

For this we will declare an array of ‘KeyValuePair’ as shown below –

private KeyValuePair<string, double>[] salesData;

Now let’s add code which will set the values of DataGrid row to our chart. For this, we have an event called ‘SelectionChanged’ as shown below –

image

Now let’s add some code for our hyperlink button which will play an animation ‘CloseButtonClicked’ as shown below –

image

Now if you run your application, you will see that your DataGrid is displaying the sales data. Click on the DataGrid row and the chart will be displayed as shown below –

Silverlight 3D Plane
If you click on ‘Close The Graph’, the DataGrid will come to its original position. Please note that this data can be fetched from a WCF service as well.

Download the source code (Blend project not included)




2 comments:

tubbut said...

Nice example. Never knew we could do anything like this in Silverlight 4.

Any idea what would I change if the same were to be attempted in SL 5? I heard it has some cool 3D capabilities built in now

Pravinkumar said...

Hi Tubbut,

Yes you are right. Silverlight 5 Beta has couple of cool 3D features. For information you can see the MIX 11 session. Here is a Link - http://channel9.msdn.com/Events/MIX/MIX11/MED06