Windows Phone 7 April CTP and TransitioningContentControl

5/20/2010 1:50:00 PM

In my original screencast (read here or on Channel 9), I showed you how to use the Silverlight Toolkit’s TransitioningContentControl to add automatic transitions between pages of your Windows Phone 7 Silverlight application.  A few days after recording and posting that screencast, Microsoft released an updated version of the tools and the emulator.  Soon after, I started to get reports from folks watching my screencast that the TransitioningContentControl not only didn’t work with the April CTP release, but it prevented their entire application from running.

Bummer! ;-)  I started to dig into it, and it “appears” that the TransitioningContentControl is suffering from the bug talked about here.  I say it “appears” to be related to that because the symptoms are the same, but unfortunately, the provided fix does not work on the System.Windows.Controls.Layout.Toolkit assembly that is created by building the Silverlight Toolkit.  I think it has something to do with the fact that the System.Windows.Controls.Layout.Toolkit project uses the output of several other projects, which are probably signed as well.  I am not sure how that propagates into the final assembly, but the Powershell script does not fix things.

To solve the problem, I just went “brute force” and added the necessary source files from the TransitioningContentControl project to my own project and called it good.  A better step would have been to break that source out into its own project and create an unsigned assembly containing just the TCC that I could then reuse between Windows Phone projects, but I am assuming at this point that whatever the bug is (signed assembly or other), will be fixed in a future release.  In the interim, this get the job done.

Watch the short video (5 minutes) to see how to get things set up.  Skip to the 2:30 mark if you want to get right to the step required to add TCC directly to your project.

Download source here

Tags:

Screencasts | Windows Phone

Simplifying Page Transitions in Windows Phone 7 Silverlight Applications

4/26/2010 1:33:00 PM

Screencast of this article is available:

Source code of sample application download here.

If you have played around with Silverlight on Windows Phone 7, one thing you may have tried to figure out is how to add nice transitions between different pages of your application.  By default, Windows Phone page transitions really aren’t transitions at all.  The new PhoneNavigationPage is just popped into the root PhoneNavigationFrame.  Effective, yes. Cool, certainly not.  Face it, modern mobile applications need to not only be functional, but also stylish.  Simple “snap” transitions just don’t cut it.

The most common solution to this problem is to use brute force and manage the transitions yourself.  You commonly see a “pattern” used in WP7 apps where events in your current page launch a Storyboard animation.  When that animation is complete, the actual navigation to the new page is invoked and the new page then runs its own Storyboard once it is loaded.  It looks something like this…

// CURRENT PAGE
       private void CurrentPage_Click(object sender, EventArgs e)
       {
           SomeStoryboard.Completed += new EventHandler(SomeStoryboard_Completed);
           SomeStoryboard.Begin();                       
       }

       void SomeStoryboard_Completed(object sender, EventArgs e)
       {
           NavigationService.Navigate(new Uri("/Favorites", UriKind.Relative)); 
       }

// NEWPAGE
protected override void OnNavigatedTo(Microsoft.Phone.Navigation.PhoneNavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    SomeNewStoryboard.Begin();
}

It’s a straightforward solution, and if your app only has a few pages, it works just fine.  If you have lots of pages in your application, however, it becomes quite tedious and hard to maintain.

A better solution can be found by turning to the Silverlight Toolkit.  The great thing about having Silverlight on WP7 is that you can leverage many existing Silverlight assets.  In this case, we will leverage the TransitioningContentControl from the Toolkit.  The TransitioningContentControl was created to solve the same problem we are facing for traditional navigation-based Silverlight application.

To get started, download the Silverlight Toolkit from CodePlex. Once installed, you will need to add the System.Windows.Controls.Layout.Toolkit assembly to your WP7 project.

If you are not familiar with the TransitioningContentControl, its a fairly simple control.  The TCC is comprised of two ContentPresenters – current and previous.  When you update the Content property of the TCC, it will take the content of the CurrentContentPresenter (if present) and move it to the PreviousContentPresenter.  The new content is loaded into the CurrentContentPresenter.  The TCC, however, manages the visibility of the previous and Current ContentPresenters so that the “old” content is visible and the “new” content is hidden.  It then uses a Storyboard that is defined as part of the TCC’s VisualStateManager to transition from the “old” content to the “new” content.  If you are not familiar with Storyboards, the Visual State Manager, or other designer-type topics, have no fear.  The TCC comes with a set of standard transitions that you can use out of the box.

Getting the TCC to work with our WP7 app is a simple process.  First, we need to modify the ControlTemplate for our PhoneNavigationFrame to use the TCC.  By doing so, we automatically enable transitions between any PhoneNavigationPages we add to our app.  To change the PhoneNavigationFrame, open the App.xaml file.  First, add a couple of namespaces to our xaml:

    xmlns:layout="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit"
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"

Now, modify the PhoneNavigationFrame as shown below:

        <phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml">
            <phoneNavigation:PhoneApplicationFrame.Template>
                <ControlTemplate>
                    <layout:TransitioningContentControl Content="{TemplateBinding Content}" Style="{StaticResource TransitioningStyle}"/>
                </ControlTemplate>
            </phoneNavigation:PhoneApplicationFrame.Template>
        </phoneNavigation:PhoneApplicationFrame>

 

The TCC has its Style property set to a StaticResource.  This Style provides the default transitions and is also where you would add your own VisualStates and Storyboards if you would like to add custom transitions.  This Style can be found in the Silverlight Toolkit in the TCC Sample Application, or you can get it from the sample WP7 application linked to this article.  The Style is long so I won’t show the entire thing here, but the first parts of the Style are below to give an idea of what the Style contains and how it is used by the TCC.

  <Style x:Key="TransitioningStyle" TargetType="layout:TransitioningContentControl">
            <Setter Property="Transition" Value="DefaultTransition" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="layout:TransitioningContentControl">
                        <Border Background="{TemplateBinding Background}" 
                                BorderBrush="{TemplateBinding BorderBrush}" 
                                BorderThickness="{TemplateBinding BorderThickness}" 
                                CornerRadius="2">
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name="PresentationStates">
                                    <vsm:VisualState x:Name="DefaultTransition">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                                                           Storyboard.TargetName="CurrentContentPresentationSite" 
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:02.300" Value="1" />
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                                                           Storyboard.TargetName="PreviousContentPresentationSite" 
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:02.300" Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="Normal">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" 
                                                                           Storyboard.TargetName="PreviousContentPresentationSite" 
                                                                           Storyboard.TargetProperty="(UIElement.Visibility)">
                                                <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>
                                                            Collapsed
                                                        </Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>

 

I won’t break the Style down in detail, but I’ll point a couple of highlights.  First, the Transition property is set to the VisualState that you would like to use as the transition between pages.  Every transition will use this VisualState storyboard.  The DefaultTransition VisualState is an example of how Storyboards are constructed for use in a transition.  As you can see, each Storyboard must target both the CurrentContentPresentationSite and the PreviousContentPresentationSite (these are the ContentPresenters discussed earlier).  You can target more than one property if you like.  Below is a custom transition that can be found in my sample app that both rotates the projection plane and the opacity of the ContentPresenters.

<vsm:VisualState x:Name="SwingTransition">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" 
                                                                           Storyboard.TargetName="PreviousContentPresentationSite">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="90"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" 
                                                                           Storyboard.TargetName="PreviousContentPresentationSite">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimation Duration="0" To="0" 
                                                             Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" 
                                                             Storyboard.TargetName="PreviousContentPresentationSite" />
                                            <DoubleAnimation Duration="0" To="1" 
                                                             Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" 
                                                             Storyboard.TargetName="CurrentContentPresentationSite" />
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" 
                                                                           Storyboard.TargetName="CurrentContentPresentationSite">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="90"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" 
                                                                           Storyboard.TargetName="CurrentContentPresentationSite">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>

 

That’s it.  You now have transitions any time you Navigate to a new PhoneNavigationPage

Tags:

Screencasts | Windows Phone

Building a Composite WPF Application Part 6: Working with Models

4/7/2009 11:36:00 AM

In this installment of the Building a Composite WPF App (Prism) series, I take a look at building models. I show why we may build View specific models and how they will be exposed by the Presenters in the Northwind Business Center application.  I say this in the screencast, but it is very possible to combine the presenter and the model into a single ViewModel, but I have kept them separate for illustration purposes. 

 

Download video here

Download source code here

Tags:

Screencasts | WPF Composite App

Building a Composite WPF Application Part 5: Building a Basic Presenter

4/6/2009 5:02:00 PM

The next installment of the Building Composite WPF app series is now available.  In this installment, I introduce building a simple View implementation in the MVP or MVVM style. The demo illustrates creating simple view that will be used to display a list of customers in our Northwind Business Center application.

 

Download video here

Download source code here

Tags:

Screencasts | WPF Composite App

Building a Composite WPF Application Part 4: Intro to Views

4/6/2009 4:16:00 PM

The next installment of the Building Composite WPF app series is now available.  In this installment, I introduce building a simple View implementation in the MVP or MVVM style. The demo illustrates creating simple view that will be used to display a list of customers in our Northwind Business Center application.

 

Download video here

Download source code here

Tags:

Screencasts | WPF Composite App

Building a Composite WPF Application Part 3: Intro to Modules

1/23/2009 8:05:00 PM

The next installment of the Building Composite WPF app series is now available.  In this installment, I introduce Modules by providing an overview of what they are and an example of the steps involved in creating one.  The demo illustrates a simple view from a Module being displayed in our Northwind Business Center application.

 

Download video here

Download source code here

Tags:

Screencasts | WPF Composite App

Developer Minute has a Heart Beat

8/22/2008 8:27:19 AM

Yep, I have finally been able to shave a little time and start working on Developer Minute.  Still in alpha stage right now, but I've made some decent progress on the Silverlight part (mostly by stealing code from here and there), but getting closer.  Besides the intro video playing, not much else is out there.  No RSS yet, I need an Episode data template to clean up the UI stuff, I want some pop-up functionality, and right now all the data is coming from Spaghetti Code screencasts (I will be putting they same functionality into my SlickThought to watch screencasts as well).  I've had some challenges getting WCF to work with my hoster so instead of dealing with some of those hassles I am changing the way I server up the RSS. 

Stay tuned...

Tags:

Screencasts | Slick Thoughts | SpaghettiCode

Spaghetti Code Almost Live - Finishing the Bayesian Filter

3/27/2008 9:02:00 PM
Another installment of the Almost Live series and the Bayesian Filter is completed.  If you haven't been following along, one of the program requirements was to be able to filter past performance data automatically.  The application, written using C#, uses a Bayesian filter to automatically filter the data and separate the data into "good" data and "bad" data, with later algorithms using the "good" data.  It is a relatively simple Bayesian filter, but it demonstrates how to go about training a filter, the roll the filter's threshold can play, and discusses some areas to build a more complex filter.  At the end of the day, it is has turned out to be a very powerful solution for filtering data, so if you are ever faced with a situation where you know what is good and bad and want to teach a computer how to approximate that same type of knowledge, a Bayesian filter could be the way to.

Source code available for download here.

Double-click for full screen

Tags:

SpaghettiCode | Screencasts

Spaghetti Code Almost Live - Building the Bayesian Filter Part I

3/18/2008 11:17:00 AM
Continuing on in the effort to add a Bayesian filter to our "analysis" program, I show you the basic steps of configuring our filter so we can train it to sift through past performance data.  It's pretty straight forward, but Bayesian filters pretty much are that way.  There is nothing complicated about them, but the results will seem almost like magic.  I show at the end of the screencast the training app used to train our filter and will provide a bit more detail on that part of the solution in the next screencast.  That is also when I will show you how we actually use the filter to analyze data and filter the good from the bad.

You can download the source here.

Note:  I accidentally set the screencast to start with the volume muted.  So you will need to click the mute button to get the sound working.  Sorry - I will try and upload a good player config later.
Double-click for full screen

Tags:

SpaghettiCode | Screencasts

Spaghetti Code 'Almost Live' - Using Reflection with Custom Attributes

2/15/2008 5:57:00 PM
In this episode, I use the custom attribute from the previous episode along with reflection to load data into a given object.  This sets the stage for being able to load all the data needed to begin to process races, and with that, to the first big step in using that data - a Bayesian Filter!  You can get the source for HorseNET up to this point by downloading it here.

Double-click for full screen

Tags:

SpaghettiCode | Screencasts

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

About the author

Jeff Brand Jeff Brand

This is the personal web site of Jeff Brand, self-proclaimed .NET Sex Symbol and All-Around Good guy. Content from my presentations, blog, and links to other useful .NET information can all be found here.

E-mail me Send mail


Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

My Twitter Updates

XBOX
Live

Recent comments

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Sign in