Posts tonen met het label Silverlight. Alle posts tonen
Posts tonen met het label Silverlight. Alle posts tonen

dinsdag 27 december 2011

Memory profiling a Silverlight Application

It’s the nightmare of most developers:  a memory leak.  Not knowing which pesky reference is holding that object in its grip or what eventhandler refuses to let go of that viewmodel.  Today I’ve had the tremendous joy (notice the sarcasm please) of solving a memory leak.  To make matters even worse, the memory leak was caused by a Silverlight application.  I’ve seen a couple of suggestions for memory profiling a Silverlight application like Davy Brion’s solution, or even tried out a couple of memory and performance profilers like the one of Jetbrains, but none that felt comfortably to work with and looked too complicated for such a simple issue.

Then after I was just about to give up, I came across RedGates ANTS memory profiler.  At first I was skeptic because it seemed like a sales person wrote the introduction page of the tool but I was pretty desperate so I filled in my personal data and downloaded the trial.  Beware though cause RedGate actually uses your data to call you later on to get feedback and to try to talk you into buying their products.

The installation was easy and straightforward and after restarting visual studio I saw the ANTS submenu appear in the menu bar.  It didn’t take me much longer after that to find the memory leak.
The actual memory leaked wasn’t mine but was introduced by a class I found on the internet, the bindinghelper http://www.scottlogic.co.uk/blog/colin/2009/02/relativesource-binding-in-silverlight/ ).  The class helps a Siverlight developer to relatively bind to a property outside a datatemplate or whatever.  

Let me explain how I found the memory leak:

At first I launched the ANT memory profiler by clicking ANTS => Profile Memory.  It then started profiling my webpage by default so I stopped profiling and then clicked File => New Profiling Session.  It then launched to following screen:



I switched the Application Type to profile to Silverlight 4 and filled in the Silverlight Application URL.  After that I clicked Start Profiling.  

After some profiling it was very obvious I was dealing with a memory leak here:



So I then took a memory snapshot:



So now what is causing this dammed memory leak?   I then clicked the Class List button which gave me a list of classes and how many instances there were and how much memory it consumed.  



I then clicked the Instance Categorizer to see the dependency graph that references all these strings.  On the far left of the screen I saw the cause of all my troubles :-).



I immediately opened the BindingHelper class and saw that objects added to its dictionary weren’t removed when they weren’t needed anymore so it was just a matter of adding the right line and voila! Memory leak solved ;-)

From this I can draw two conclusions:

The first is never to trust code coming from the internet.  Allot of bloggers submit code that hasn’t been tested on the long run and is merely intended as a reference and not as a solution.

The second is that RedGates ANTS memory profiler is one sweeeeet profiler.  You don’t have to be a rocket scientist to use it and it show some nice graphs, and admit it, who can say no to pretty graphs and diagrams. 

Till next time!

maandag 14 november 2011

Silverlight Developers are worried

It kind of feels like another episode of a dramatic television soap.  If you’ve been in a coma for the previous 5 months let me refresh your memory:


Then in episode 2 we then saw that HTML and Javascript will be technologies that you can use in Windows 8 but you can still write your everyday XAML and use the WinRT API’s for your metro apps.  You can even still use .NET for your 'legacy' applications.

In episode 3 Microsoft announced that they’ll be ditching browser plugins in the metro version of IE and will only make them available in legacy desktop mode.  Another sad episode indeed, the part that made allot of people cry was quote:

For what these sites do, the power of HTML5 makes more sense, especially in Windows 8 apps.

Now for the cliffhanger of this seasons ‘bye bye silvy’ rumors are going that Silverlight 5 will be the last Silverlight version released.  Will this turn out to be true?



Since the release of this rumor my blog visitors have spiked and one post in particular received allot of views.  Based on this and the ranting that’s going on several forums I think it’s safe to say that allot of Silverlight developers are worried for their future.

But should you be worried?  After all the technology isn’t likely to go away the next couple of years, Silverlight 5 still has to be released.  But what company is going to invest in a project that makes use of a technology that is already deprived of its future?  Wouldn’t it make more sense to switch to HTML 5 instead?

Then again Silverlight will still be used in Windows Phone 7 and Xbox…. not really useful if you’re a corporate developer (unless you work at a company that uses Xbox's for their business apps).  Okay granted that there will certainly be a future for Silverlight in Windows Phone 7, but how long will it take for Microsoft to merge their desktop OS with their Phone OS, seeing that we already have quad core mobile CPU’s.

I don’t think Silverlight developers should worry just yet, the transition will go smoothly and there are still a ton of Silverlight applications that need to be maintained (or rewritten).  Though it won’t hurt you to start refreshing that good old HTML and Javascript as it looks that you’ll be needing it in the near future…

dinsdag 20 september 2011

No Silverlight for your Metro browser

I’ve just read that IE10 metro won’t support the Silverlight plugin anymore (1,2).  The reasons behind this decision are that they want to make the browser less resource extensive.  Microsoft appears to be aiming for an entire HTML5 supporting browser.  They say that the plugins drain too much battery life with their updates and that they’re not always that secure.

IE10 will come in two flavors with one core, so you’re not completely lost.  The desktop version of IE10 will support plugins.

I think it’s a bit of a mistake that Microsoft won’t allow plugins in the metro version.  It would provide them with the edge they need over other vendors that don’t support Flash and Silverlight.  Though it seems that together with Windows 8, they’re looking to make the whole metro experience as smooth as possible and are eliminating as many risks as possible.

Switching from Metro mode to desktop mode appears to be very easy , if we believe the Building Windows8 blog:
On Windows 8, consumer sites and “line of business” applications that require legacy ActiveX controls will continue to run in the desktop browser, and people can tap “Use Desktop View” in Metro style IE for these sites. For what these sites do, the power of HTML5 makes more sense, especially in Windows 8 apps.
It appears Microsoft is really discouraging developers from using plugins in their website. With allot of big players jumping on the HTML5 bandwagon the clock seems to be ticking for browser plugins…

woensdag 7 september 2011

Is Silverlight the future or the past?

The Silverlight community has been startled since the day Microsoft announced that HTML5 will be an important technology in the desktop environment for Windows 8.  Some of the initial reactions were:
  • we've just been F****D.
  • It's time to flee away from MS, they are just insane.  Looks like Vista "success" was not enough for them
Let’s evaluate.

JavaScript

Some people claim that it is impossible to run the extensive business apps that we have today with HTML5 and JavaScript.  The code would simply be to complex, and the JavaScript technology is too limited.

But is it? There are numerous examples of online JavaScript applications that will blow your mind.  Here are some examples of very complex JavaScript applications:

So if we can build all the above using JavaScript then why wouldn’t we be able to build a ‘simple’ business application using JavaScript?  I welcome HTML and JavaScript to the Windows desktop experience and it is a smart move by Microsoft.

The HTML and JavaScript will probably be combined with the existing .NET technology anyways so why should the average .NET developer worry?  The front end changes but does that mean you will have to throw away all of your code?

Will Microsoft drop WPF and Silverlight?

I find it humorous how many people have asked this question.  The answer is simple: NO.  

They won’t drop WPF and Silverlight… not within the next 5 to 10 years they won’t.   If Microsoft would drop these technologies and stop their support then they would simply be kicking their self’s in the groin (and I have no idea how you would be able to kick yourself in the groin).  

The number of existing Silverlight and WPF are staggering, even though many people think otherwise.  At the moment, statistics show that Silverlight 4 is installed on 71% of all browsers.  Fair enough compared to the 96% of Flash it seems a bit low, but keep in mind that Flash has been around for more than three times as long as Silverlight and has some big players behind them.

Truly cross platform

I once read this article where the author claimed that .NET could possible just be a mistake.  Though I do not agree with all he said, he did have some very valid points.  As the writer in this article mentioned one off the initial selling points of the .NET framework was that it was platform agnostic.  After almost 10 years we can come to the conclusion that this is not truly the case.  It has the potential, but it never reached that point.

So what about Silverlight?  Is Silverlight platform agnostic?  Initially this seems to be the case.  90% of the time you write a Silverlight application, you’ll be able to run it on Windows and Mac.  Linux however is another story.  If you want your Silverlight application to run on Linux with Moonlight then be sure to downgrade a version and even then chances are you’ll bump into problems.

The problem is that a 90% success rate at best for a platform agnostic web application is not enough.  The times you’ll want your application to be platform independent are the times you’ll be making your application available to a wide range of users.  If you, as a company, will be making your application to be publically available then you want to be assured that nothing will go wrong.  It’s your company’s reputation on the line.

At this moment the only true platform agnostic technology is JavaScript and HTML.  It’s proven, sound and has had a long past behind it.  

Silverlight will survive

It seems like the HTML5 news is the only news that the Silverlight community pays attention to. Silverlight is more than just a browser plugin.  It has become the main application platform for Windows Phone 7 and it will likely be the application platform for XBOX .  

If you see it like that then you come to realize that Microsoft might have a bigger future in plan for Silverlight than most developers think.  It might become the unification platform for XBOX, Windows and Windows Phone. 

On the other side: "The future has a way of arriving unannounced." -George Will

We’ll just have to wait and see :-)

donderdag 1 september 2011

Linking an entity between web domain services in RIA services


I’m not the biggest fan of RIA services, but I was pretty surprised the other day when I saw how easily RIA handled the sharing and linking of entities trough different domain services.
So suppose we have the following table structure in our database:


As you can see we have 2 tables: Person and Function.  Then we can generate our web domain services by adding an edmx and then adding a domain service class to the solution.



So I told you nothing new at this moment.  
Now imagine evil reincarnated into a person.  We’ll call this person the customer. One day he comes to you and says: “We’ll need to split the Person table to a centralized database for reuse”.  As soon as you realize he is serious your face will probably be going this way:

But have no fear (RIA is here) because it’s actually pretty easy to accomplish this in RIA services!

At first you’ll need to create a new edmx.  The reason why is because the edmx is basically wrapped around one connection string so for each separate connection you’ll need to create a new edmx.

So the 2 databases will look like this:



And the edmx’s will look like this:



Then build the solution.  Before you can build it you’ll have to remove the person operations from the first domain context.  The reason why you have to do this is because your first domain context inherits from LinqToEntitiesDomainService<FirstDatabaseEntities>. The underlying ObjectContext won’t have any reference any more to the Person entityset that you’ve just deleted.

If you have navigation properties defined in the metadata file then you should delete these also to be able to build.

If you are receiving build errors in your Silverlight projects (which will be very likely), then just ignore these.  It is only essential that you’re able to build the web projects.

Then add a new RIA web domain service class generated from the second database and select the tables you want.  



So now you’ll need to tell RIA services that the Function class in the first entity model is linked to the Person class in the second entity model.  To do this you’ll have to create a partial class of the Function entity.  Now add a property there that will return the Person.  The property must be decorated like so:

public partial class Function
{
    [ExternalReference]
    [Association("Person_Function", "PersonId", "ID")]
    public Person Person { get; set; }
          
}

The External reference attribute will tell the current domain service that the entity this property is returning is from an external domain context.  

The Association attribute will tell the domain service how to link the entities together.  What this will actually do is generate code on the client side that will filter the appropriate entity out.

When you’re finished doing this, build the solution to trigger the code generation client side.  Then you can open the generated file and see that it generated the following code:

public global::DomainService.Web.Person Person
{
    get
    {
        if ((this._person == null))
        {
            this._person = new EntityRef<global::DomainService.Web.Person>(this, "Person", this.FilterPerson);
        }
        return this._person.Entity;
    }
}

private bool FilterPerson(global::DomainService.Web.Person entity)
{
    return (entity.ID == this.PersonId);
}

Notice the generation of the filter depending on the parameters we gave to the Association attribute.

If you’re not interested in coupling the entities server side, then you can always manually couple the entities on the client side with a partial class that has the same code as the generated file.  Either way the client side code will be practically the same.

Now we still need to tell our context object where to find the associated Person entity.  We can do this by calling the AddReference method and supply the Person type and the corresponding context in which the Person entity resides.

_context1 = new DomainService1();
_context2 = new DomainService2();

_context1.AddReference(typeof(Person),_context2);

When this is done you just need to retrieve the data from the server and tadaaaa:

var personQuery = _context2.GetPersonQuery();
_context2.Load(personQuery, PersonLoadCompleted, true);


void PersonLoadCompleted(LoadOperation<Person> loadOperation)
{
    var nrOfEntitiesReturned = loadOperation.AllEntities.Count();
    MessageBox.Show(nrOfEntitiesReturned.ToString());

    var functionQuery = _context1.GetFunctionQuery();
    _context1.Load(functionQuery, FunctionLoadCompleted, true);
}

void FunctionLoadCompleted(LoadOperation<Function> loadOperation)
{
    var personOfFunction = loadOperation.Entities.First().Person;
    MessageBox.Show(personOfFunction.Name);
}

Some special notes to pay attention to:
  • Name the relation the same as the entity you are returning
    I find this a very strange implementation but if you name the navigation property different then for some strange reason RIA services won’t generate the relation properly
  • Make sure you don’t have any include attributes above the external reference in you metadata class
    When you do this RIA services will generate an objectset within the service context of that type.  This will generate errors when you’re trying to couple the entity type between the two service contexts.
That’s it, till next time!

donderdag 4 augustus 2011

Html + jQuery vs Silverlight: part 3. Graphs

In the previous Html + jQuery vs Silverlight blogposts (1) (2) I discussed animations and how the two technologies compared to each other. Now we will see how the two measure up when displaying statistical data.

For the Silverlight side I will be using the Silverlight toolkit.  Granted that there are better solutions but most of these have a price tag assigned to them.  For the jQuery I will be using jqPlot.  I’m not sure whether this is the best solution but there are so many of these libraries out there that it is impossible to try them all out.  If you find that you have a better alternative than by all means post it.

The datasource I will be using for both examples is a fictional list of visitors for a blog. 
So let’s start building.  As usual I’ll be starting with Silverlight since this is the technology I have the most experience with. 

So at first we create a datasource for the graphs to be able to bind to:

Resources.Add("PageViews", new List<PageView>()
                {
                    new PageView(){Amount = 5000, Date = new DateTime(2011,1,1)},
                    new PageView(){Amount = 6000, Date = new DateTime(2011,2,1)},
                    new PageView(){Amount = 7000, Date = new DateTime(2011,3,1)},
                    new PageView(){Amount = 7500, Date = new DateTime(2011,4,1)},
                    new PageView(){Amount = 8100, Date = new DateTime(2011,5,1)}
                });

Now that this is done we create our graphs in the page and databind to our datasource:

<toolkit:Chart Grid.Row="0">
    <toolkit:Chart.Series>
        <toolkit:ColumnSeries
                    ItemsSource="{StaticResource PageViews}"
                    IndependentValueBinding="{Binding Date}"
                    DependentValueBinding="{Binding Amount}"/>
    </toolkit:Chart.Series>
</toolkit:Chart>
<toolkit:Chart Grid.Row="1">
    <toolkit:Chart.Series>
        <toolkit:PieSeries
                    ItemsSource="{StaticResource PageViews}"
                    IndependentValueBinding="{Binding Date}"
                    DependentValueBinding="{Binding Amount}"/>
    </toolkit:Chart.Series>
</toolkit:Chart>
<toolkit:Chart Grid.Row="2">
    <toolkit:Chart.Series>
        <toolkit:LineSeries
                    ItemsSource="{StaticResource PageViews}"
                    IndependentValueBinding="{Binding Date}"
                    DependentValueBinding="{Binding Amount}"/>
    </toolkit:Chart.Series>
</toolkit:Chart>

So that's it for Silverlight. How does jQuery compare towards this slick implementation?  Not that different!
Again we create our datasource:

var data = [['2011-01-01', 5000], ['2011-02-01', 6000], ['2011-03-01', 7000], ['2011-04-01', 7500], ['2011-05-01', 8100]];

Then we speak to our third party library to plot the graphs:

var line = $.jqplot('chart1', [[5000,6000,7000,7500,8100]], {
    cursor: { show: true },
    highlighter: { show: true },
    seriesDefaults: {
        renderer: $.jqplot.BarRenderer,
        rendererOptions: { fillToZero: true }
    },
    axesDefaults: {
        labelOptions: {
            fontSize: '13pt'
        }
    }
});


var pie = $.jqplot('chart2', [data], {
    series: [{
        renderer: $.jqplot.PieRenderer,
        rendererOptions: {
            sliceMargin: 3,
            showDataLabels: true,
            dataLabelNudge: 20
        }
    }],
    legend: {
        show: true
    }
});

var bar = $.jqplot('chart3', [data], {
    axesDefaults: {
        labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
        labelOptions: {
            fontSize: '13pt'
        }
    },
    axes: {
        xaxis: {
            renderer: $.jqplot.CategoryAxisRenderer
        }
    }
});

The chart1, chart2 and chart3 identifiers are from 3 divs declared in the body:

<div id="chart1" style="height: 300px; width: 600px;">
</div>
<div id="chart2" style="height: 340px; width: 500px;">
</div>
<div id="chart3" style="height: 340px; width: 500px;">
</div>
So both implementations are pretty smooth, although it is pretty obvious that the XAML is way more expressive than the jQuery. Why would you favor jQuery over Silverlight then?  The usual Achilles heel of Silverlight is the plugin so I’m not bothering elaborating that even further.   

Rendering

This was a remark I made in the previous post but in this library I can’t say the Silverlight implementation is that much better than the jQuery implementation.  It does have some better rounded edges and the rendering has no difference in between browsers but besides that they both look nice.



Browser support:

It was fun to see that both examples worked in all browsers for both solution soI have no problem here.

Performance:

The drawing is pretty much identical on both technologies, yet if you opt for the Silverlight solution then you have the drawback of downloading the XAP.  The size of the XAP when fully stripped of all unnecessary assemblies is 360 KB, while the jquery solution with all scripts would account for 210 KB.  That’s not a big difference! The problem however is that the XAP still needs to be processed and loaded into the runtime.  For that reason the Silverlight solution takes around 3 times longer to load then the jQuery solution.

To conclude I would say that this round is favored for jQuery.  It’s much faster (to load) and there is a whole arsenal of free libraries at your disposal.  The rendering is pretty much the same and you don't need a plugin.

Till next time!

woensdag 20 juli 2011

Html + jQuery vs Silverlight: part 2. 3D Navbar with flying views

In theprevious post I gave a basic comparison between jQuery and Silverlight based on simple animations.  Today, I’ll be taking the animations a step further. 

I’m going to attempt to make a simple semi-3D UI with some animations, first in Silverlight and then in jQuery.  As I said in the previous post, I’m no jQuery expert so if there are simpler ways for doing the things I’m attempting here than just let me know.  Let’s get started.

Let me start by explaining the idea for the UI.  As always I’ll use the only tool I can call myself professional in… paint.



So the idea would be that Panel1 would rotate around its Y axis to provide a 3d like side panel (my paint skills proved inadequate so you’ll have imagine it).  The rotation should happen when the user starts up the page so we get a neat star trek / minority report like effect.  Then when one of the buttons is clicked, a view is loaded on the right side.  When the view comes into screen it will slide in from bottom to top.  If a view is already loaded then that view will slide away to the top.  

This is how the page translates in Silverlight:

At first we’ll need to create a page with a grid that has 2 columns:  one for the 3D panel and one for the View sliding in.  Since this is just a demo, I’ll be loading in a Usercontrol as a view instead of a whole page.
So in our main page we have the following code:

       <Grid x:Name="LayoutRoot" Background="White">
             <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Loaded" SourceName="stackPanel">
                          <ei:GoToStateAction StateName="End"/>
                    </i:EventTrigger>
             </i:Interaction.Triggers>
             <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="VisualStateGroup">
                          <VisualStateGroup.Transitions>
                                 <VisualTransition GeneratedDuration="0:0:3"/>
                                 <VisualTransition From="Begin" GeneratedDuration="0:0:3" To="End"/>
                          </VisualStateGroup.Transitions>
                          <VisualState x:Name="Begin"/>
                          <VisualState x:Name="End">
                                 <Storyboard>
                                       <DoubleAnimation Duration="0" To="-20" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
                                       <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
                                       <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
                                       <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationY)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
                                 </Storyboard>
                          </VisualState>
                    </VisualStateGroup>
             </VisualStateManager.VisualStateGroups>
             <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="150"/>
                    <ColumnDefinition Width="*"/>
             </Grid.ColumnDefinitions>
             <StackPanel x:Name="stackPanel" VerticalAlignment="Stretch" Background="#FFD4D4D4">
                    <StackPanel.Projection>
                          <PlaneProjection/>
                    </StackPanel.Projection>
                    <i:Interaction.Triggers>
                                 <i:EventTrigger EventName="Loaded">
                                       <ei:GoToStateAction TargetName="View1" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View2" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View3" StateName="Out">
                                       </ei:GoToStateAction>
                                 </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <Button Margin="0,5,0,5" Content="Button1">
               
                          <i:Interaction.Triggers>
                                 <i:EventTrigger EventName="Click">
                                       <ei:GoToStateAction TargetName="View1" StateName="In">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View2" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View3" StateName="Out">
                                       </ei:GoToStateAction>
                                 </i:EventTrigger>
                          </i:Interaction.Triggers>
               
                    </Button>
                    <Button Margin="0,5,0,5" Content="Button2">
                           <i:Interaction.Triggers>
                                 <i:EventTrigger EventName="Click">
                                       <ei:GoToStateAction TargetName="View1" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View2" StateName="In">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View3" StateName="Out">
                                       </ei:GoToStateAction>
                                 </i:EventTrigger>
                          </i:Interaction.Triggers>
                    </Button>
                    <Button Margin="0,5,0,5" Content="Button3">
                                                    <i:Interaction.Triggers>
                                 <i:EventTrigger EventName="Click">
                                       <ei:GoToStateAction TargetName="View1" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View2" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View3" StateName="In">
                                       </ei:GoToStateAction>
                                 </i:EventTrigger>
                          </i:Interaction.Triggers>
                    </Button>
             </StackPanel>
             <local:viewControl x:Name="View1" Grid.Column="1" d:LayoutOverrides="Width, Height" Background="#FFFFB0B0"/>
             <local:viewControl x:Name="View2" Grid.Column="1" d:LayoutOverrides="Width, Height" Background="#FFE8FFAA"/>
             <local:viewControl x:Name="View3" Grid.Column="1" d:LayoutOverrides="Width, Height" Background="#FF89D0FF"/>
       </Grid>
</UserControl>

As you can see the 3D effect is very easy to do in Silverlight by transforming the control.  The animation can be simply triggered by a GoToStateAction, so no code required.  In this page there are only 2 states defined called begin and end.  These states are for the 3D effect in the side bar.

Then we create a Usercontrol that will represent our Views.  Below is the markup for the Usercontrol:

       <Grid x:Name="LayoutRoot" Width="250" Height="250" RenderTransformOrigin="0.5,0.5" Background="{Binding Background, ElementName=userControl}" DataContext="{Binding Source={StaticResource Text}}">
             <Grid.RenderTransform>
                    <CompositeTransform/>
             </Grid.RenderTransform>
             <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="VisualStateGroup">
                          <VisualStateGroup.Transitions>
                                 <VisualTransition GeneratedDuration="0:0:1"/>
                                 <VisualTransition From="Begin" GeneratedDuration="0:0:1" To="In"/>
                                 <VisualTransition From="In" GeneratedDuration="0:0:1.0001" To="Out"/>
                                 <VisualTransition From="Out" GeneratedDuration="0" To="Begin"/>
                                 <VisualTransition From="In" GeneratedDuration="0" To="Begin"/>
                          </VisualStateGroup.Transitions>
                          <VisualState x:Name="Begin">
                                 <Storyboard>
                                       <DoubleAnimation Duration="0:0:1.5" To="-600" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="LayoutRoot" d:IsOptimized="True"/>
                                 </Storyboard>
                          </VisualState>
                          <VisualState x:Name="In"/>
                          <VisualState x:Name="Out">
                                 <Storyboard>
                                       <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="LayoutRoot" d:IsOptimized="True">
                                              <LinearDoubleKeyFrame Value="600" KeyTime="0:0:1"/>
                                              <LinearDoubleKeyFrame Value="-600" KeyTime="0:0:1.0001"/>
                                       </DoubleAnimationUsingKeyFrames>
                                 </Storyboard>
                          </VisualState>
                    </VisualStateGroup>
             </VisualStateManager.VisualStateGroups>
       </Grid>

Again very easy markup.  We create three states for our animation. 
  • The Begin state will set the layoutroot to the bottom of the page where we wait for the animation.
  • The In state will be our layout in its original position
  • The Out state will be our layout root set to the top of our page
Now when we have our views with the appropriate state you can see in the markup of the page that we trigger a different state with each button.  For example on Button1 we want the first view to come in and the other views to go out. 

       <Button Margin="0,5,0,5" Content="Button1">
               
                          <i:Interaction.Triggers>
                                 <i:EventTrigger EventName="Click">
                                       <ei:GoToStateAction TargetName="View1" StateName="In">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View2" StateName="Out">
                                       </ei:GoToStateAction>
                                       <ei:GoToStateAction TargetName="View3" StateName="Out">
                                       </ei:GoToStateAction>
                                 </i:EventTrigger>
                          </i:Interaction.Triggers>
               
                    </Button>

The total markup code for this example was approximately 160 lines.  As you can see, it’s clear that Silverlight was made for this kind of stuff.  The markup is easy to understand and even without blend you can build a very solid UI.  The beauty of this all is that you don’t have to write a single line of C# (or VB.NET) to trigger the animations.

Now let’s do the same in jQuery.

At first we’ll create our html:

    <div style="width: 500px; height: 400px;">
        <div id="SideBar" style="background: grey; height: 450px; width: 150px;">
            <button id="button1" style="width: 140px; margin: 10px 0px 10px 0px">
                Button1</button>
            <button id="button2" style="width: 140px; margin: 10px 0px 10px 0px">
                Button2</button>
            <button id="button3" style="width: 140px; margin: 10px 0px 10px 0px">
                Button3</button>
        </div>
        <div id="View1" style="width: 250px; height: 250px; background: lightblue; position: absolute;
            top: -800px; left: 200px;">
        </div>
        <div id="View2" style="width: 250px; height: 250px; background: lightgreen; position: absolute;
            top: -800px; left: 200px;">
        </div>
        <div id="View3" style="width: 250px; height: 250px; background: lightpink; position: absolute;
            top: -800px; left: 200px;">
        </div>
    </div>

So the html is no rocket science, now we need to apply the transformations.  To do this I cheated a little bit and I searched for a jQuery library that can do the 3D transformation for me. The one I ended up using is Rotate3Di .

So on the load of the document we start the animation that will rotate our panel.  Then when one of the buttons is clicked, we animate the div’s properly:

    <script type="text/javascript" language="javascript">
        $(document).ready(function () {
            $('#SideBar').rotate3Di(-15,3000);
        });
        $(":button").click(function () {
            if (this.id == "button1") {
                $("#View1").css("top", 800);
                $("#View1").animate({ top: "20px" }, 1500);
                $("#View2").animate({ top: "-=600px" }, 1500);
                $("#View3").animate({ top: "-=600px" }, 1500);
            }
            else if (this.id == "button2") {
                $("#View2").css("top", 800);
                $("#View2").animate({ top: "20px" }, 1500);
                $("#View1").animate({ top: "-=600px" }, 1500);
                $("#View3").animate({ top: "-=600px" }, 1500);
            } else if (this.id == "button3") {
                $("#View3").css("top", 800);
                $("#View3").animate({ top: "20px" }, 1500);
                $("#View1").animate({ top: "-=600px" }, 1500);
                $("#View2").animate({ top: "-=600px" }, 1500);
            }
        });
       
    </script>

To my surprise the Html and jQuery solution is smaller than the Silverlight one!  Only 44 lines!  The code does seem awfully similar to Silverlight.  This could be tribute to the fact that I first made the Silverlight application thus had the solution branded in my head, or it could be that they just do exactly the same thing besides expressing it in a different way, one in a more declarative way while the other in an imperative way.

So then why should you use Silverlight as it just brings in the overhead of installing a plugin and does not make your life easier?  Well there are a couple of reasons why in this example you would take Silverlight over the jQuery solution.

First of all, the rendering kind of sucks when doing it with jQuery.  Look at the two screenshots and tell me which looks better:


This is off course tribute to the fact that Silverlight has lots of fancy neat rendering tricks.

Another reason why Silverlight might be preference for this kind of stuff is because everything I did to achieve this was native to Silverlight.  I did not have to search for any third party scripts, though this could also be a problem because with Silverlight I am completely dependent on the implementation of Microsoft. 

The Silverlight solution is truly cross browser.  I have tried it on Chrome, Firefox and Internet Explorer and all of them render the solution exactly the same.  The jQuery solution isn’t.  On IE it would not work and the rendering was different on Chrome and Firefox.

Yet jQuery does have the big advantage by not needing any third party add-ins to run in your browser.  This might seem trivial compared to the disadvantages but it’s not.  Customers located in hospitals or other facilities, where an update requires a whole regime of acceptance tests, will be left in the cold if you develop this in Silverlight. 

The Html and jQuery solution also uses long proven technologies and with the forthcoming Windows 8 they aren’t likely to disappear soon.  Silverlight on the other is rather new and has an uncertain future.  It’s doubtful it will go away within a couple of years but its focus is shifting more and more away from the web.

That’s it for today, till next time :)

Note: files and examples will be up at the end of this week.