Turnstile transition v2.0

•May 14, 2012 • 10 Comments

Mark Monster kiddingly commented on my last post that a continuum transition in combination with the turnstile, would be awesome.

As I always take things like feedback drop dead serious (not really, just thought it was a good idea), I decided to give it a go.

Like any good developer, my quest began with a bing search, which lead me to this post;

http://benjii.me/2011/11/continuum-transition-for-windows-phone-silverlight-toolkit/

I have integrated Ben’s solution into the toolkit and completely rewrote the rest to make it fit with the turnstile transition.

End result is;

It turned out rather nice, I think Glimlach

You can label items for Continuum animation with the attached property ItemContinuumMode from the ItemTurnstileTransition class, like so;


ItemTurnstileTransition.SetItemContinuumMode(someElement as UIElement, ContinuumModeEnum.ForwardOutBackwardIn);

or in XAML, like so;


<Button BorderThickness="0" krempel:ItemTurnstileTransition.ItemContinuumMode="BackwardIn" krempel:ItemTurnstileTransition.IsTurnstileItem="True" Height="173" Width="346" Background="{StaticResource PhoneAccentBrush}" Click="Button_Click" />

I have also made some small adjustments to the previous turnstile. You can now set the IsSelected attached property, so that the item is delayed in turnstiling. Hope you enjoy it!

Source can be found here and the NuGet package here.

Let me know what you think in the comments!

Turnstile Transition

•May 9, 2012 • 14 Comments

It has always bugged me that the cool native turnstile animations for Windows Phone 7 are not natively available to developers. Rather then sit around and mope about it, I’ve implemented my own Turnstile transition.

I know that there are a couple of other turnstile controls out there, but they require you to use a custom itemscontrol and they animate on the ui thread. That’s not very cool, we should be able to turnstile what we like, regardless of what itemscontrol or contentcontrol our items are hosted in and it’s also better to animate them on the compositor thread, as we can do calculations or data retrieval when navigating (who actually does that?).

Without further ado, I present my turnstile transition based on the excellent Silverlight Toolkit for Windows Phone 7.

As you have come to expect from me, the transition is very easy to use. Just set up your normal page transitions as you would using the toolkit.

First, you have to replace the normal PhoneApplicationFrame with the TransitionFrame from the toolkit in the App.xaml.cs.

// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized) return;

// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
//RootFrame = new PhoneApplicationFrame();
RootFrame = new Microsoft.Phone.Controls.TransitionFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;

// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;

// Ensure we don't initialize again
phoneApplicationInitialized = true;
}

Then in your page, set up the turnstile transition like so;

<toolkit:TransitionService.NavigationInTransition>
<toolkit:NavigationInTransition>
<toolkit:NavigationInTransition.Backward>
<krempel:ItemTurnstileTransition XMode="BackwardIn" YMode="BottomToTop" />
</toolkit:NavigationInTransition.Backward>
<toolkit:NavigationInTransition.Forward>
<krempel:ItemTurnstileTransition XMode="ForwardIn" YMode="BottomToTop" />
</toolkit:NavigationInTransition.Forward>
</toolkit:NavigationInTransition>
</toolkit:TransitionService.NavigationInTransition>

<toolkit:TransitionService.NavigationOutTransition>
<toolkit:NavigationOutTransition>
<toolkit:NavigationOutTransition.Backward>
<krempel:ItemTurnstileTransition XMode="BackwardOut" YMode="TopToBottom" />
</toolkit:NavigationOutTransition.Backward>
<toolkit:NavigationOutTransition.Forward>
<krempel:ItemTurnstileTransition XMode="ForwardOut" YMode="TopToBottom" />
</toolkit:NavigationOutTransition.Forward>
</toolkit:NavigationOutTransition>

</toolkit:TransitionService.NavigationOutTransition>

You can change the XMode and the YMode to your wishes, but I suggest you leave it like this, as it gives the best experience.

Now that the transitionframe and the transition are in place, it’s time to let the transition know what elements it should turnstile.

<Button krempel:ItemTurnstileTransition.IsTurnstileItem="True" x:Name="ButtonHTMLTextBlock" Content="HTMLTextBlock" Click="ButtonHTMLTextBlock_Click" />

You can do this by setting the attached property to true. Now the transition will animate the button, regardless of what itemscontrol or contentcontrol it is in!

How cool is that!?

Source code is available at Krempel’s WP7 Codeplex project and NuGet package will follow suit!

Any questions are welcome in the comments section.

PullToRefreshPanel

•April 20, 2012 • 14 Comments

It has been a while since I blogged, it’s been busy. I have been neglecting my certifications, so I have got two and I am going for the third.

Never the less, no more excuses, let us get on with the show!

HTMLTextBlock update

I have updated the HTMLTextBlock, some bug fixes small bugfixes that you guys have asked for.

The control right now is basically a stack of RichTextBoxes with HTML translated to RichText XAML. For a future version I might drop this approach to support more rich layout features, such as tables. I am looking to build a visual tree from HTML and use the RichTextBox for displaying formatted text. I will keep you updated on my progress.

PullToRefreshPanel

For managing the playlist in the Channel9 Client for Windows Phone 7 I have used the excellent rearrangelistbox (also included in this release) from Jason Ginchereau. As a little treat inside the download of his control there is the PullDownToRefresh panel, which I have used extensively throughout the application. As he describes here, Mango changed the way the scrollviewer notifies the environment when it is stretched down. As an alternative he recommends changing the ManipulationMode of the ScrollViewer. But I have an alternative Glimlach.

Since Mango the scrollviewer works with VisualStates. The only problem is, the default template for the scrollviewer (the one in XAML) does not have these visual states. The scrollviewer can not find these states and does not transition to another visual state. The solution is to override the default style, with one of our own. This will require a little effort from your end. Copy and paste the following XAML fragment into your resource file (i.e. App.XAML);

<Style TargetType="ScrollViewer">
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ScrollStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Scrolling">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="VerticalScrollBar" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="HorizontalScrollBar" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="NotScrolling">
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="VerticalCompression">
<VisualState x:Name="NoVerticalCompression"/>
<VisualState x:Name="CompressionTop"/>
<VisualState x:Name="CompressionBottom"/>
</VisualStateGroup>
<VisualStateGroup x:Name="HorizontalCompression">
<VisualState x:Name="NoHorizontalCompression"/>
<VisualState x:Name="CompressionLeft"/>
<VisualState x:Name="CompressionRight"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Margin="{TemplateBinding Padding}">
<ScrollContentPresenter x:Name="ScrollContentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
<ScrollBar x:Name="VerticalScrollBar" IsHitTestVisible="False" Height="Auto" Width="5" HorizontalAlignment="Right" VerticalAlignment="Stretch" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Value="{TemplateBinding VerticalOffset}" Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}" />
<ScrollBar x:Name="HorizontalScrollBar" IsHitTestVisible="False" Width="Auto" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Value="{TemplateBinding HorizontalOffset}" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

(Press Control K + D in Visual Studio after pasting.
Now we can listen for changes in the VisualState of the ScrollViewer to detect stretches (compression) to the various sides. How to use the control? Like all of my controls the usage is relatively straightforward Knipogende emoticon

<krempel:PullToRefreshPanel IsRefreshing="{Binding Loading}" StretchToDetect="Top" RefreshRequested="Refresh" PullingDownTemplate="{StaticResource PullUpAndHoldTemplate}" ReadyToReleaseTemplate="{StaticResource ReleaseToRefresh}" />
<toolkit:LongListSelector />  
<krempel:PullToRefreshPanel IsRefreshing="{Binding Loading}" StretchToDetect="Bottom" RefreshRequested="LoadMore" PullingDownTemplate="{StaticResource PullDownAndHoldTemplate}" ReadyToReleaseTemplate="{StaticResource ReleaseToLoadMore}" />

The PullToRefresh panel will search its parent container for the first ScrollViewer it can find. In this case the ScrollViewer of the LongListSelector. It then attaches an event handler to the VisualStateChanged event of the ScrollViewer and performs its magic The PullToRefreshPanel has several visual states which are toggled by a combination of the visualstate changes of the ScrollViewer and properties set on the panel. With the StretchToDetect property you can decide which of the stretches you want to react to. Then the user needs to hold the stretch for an amount in time set in milliseconds on the StretchDelay property. If all conditions are a go, the RefreshRequested eventhandler is executed. You can prevent multiple refreshes by setting the IsRefreshing property. There are three templates which can be used to display the different states of the panel;

  1. PullingDownTemplate, this will appear when the ScrollViewer is in the specified stretch mode
  2. ReadyToReleaseTemplate, this will appear after the specified timeout
  3. RefreshingTemplate, this will appear when the control is refreshing

So there you have it!

Download including an awesome example are available on CodePlex and the package is going to be updated in NuGet, soonish!

Let me know what you think in the comments!

Next time I will feature my piece de resistance turnstile navigation animation based on the Silverlight Toolkit for Windows Phone 7 Navigation animations!

Krempel’s WP7 Library now availible on NuGet

•March 20, 2012 • Leave a Comment

One of my dear readers suggested that I put up the project up on NuGet.

And now it’s so!

You can find the package here.

Or install it via the NuGet command; “Install-Package Krempel.WP7”.

Stay tuned for more WP7 goodness, next blog will be about a pull to refresh panel!

DelayLoadImage

•March 19, 2012 • 1 Comment

With the release of Mango downloading bitmaps from the internet was moved to the background. That is indeed a very good feature, but it lacks something crucial;

It does not give you an option to display a local stored image while you wait for the download to complete.

Enter the DelayLoadImage control!

This control uses all the benefits of a BitMapImage (async download and image caching) and it gives you the option to set a local bitmap as default image. When the image is downloaded from the internet the default image will fade-out gracefully and the new image will gracefully fade-in. In my opinion this is better then an image appearing out of thin air.

Example use;

<krempel:DelayLoadImage DefaultImageSource="/Resources/standard.png" ActualImageSource="http://media.ch9.ms/ch9/7c3c/95d7cb73-b2cd-4f67-b966-0700a2847c3c/VSToolbox29_512.jpg" />

Yes, it’s that simple Glimlach

Download the new release from codeplex!

Now as promised in my previous post an update to the HTMLTextBlock.

Improvements;

  • Styles for H1, H2, H3 and Anchor elements
  • BackgroundBrush for BlockQuote elements
  • Fixed imagesize problem
  • Added Command and event handler to handle navigation

Also part of the release is a multibinding solution that I found here.

I’m in the process of writing a NuGet package for the package, so stay tuned!

Microsoft Media Platform on Windows Phone 7 and fast resume

•March 15, 2012 • Leave a Comment

The Microsoft Media Platform: Player Framework is the player of choice for the Windows Phone 7, if you want to do anything with media in your application. For the Channel9 Client for Windows Phone 7 I have used it in combination with the IIS Smooth Streaming Client 1.5 plugin, as Channel9 provides excellent streams for their most popular videos.

To use the player is very straightforward;

  • Download the binaries from Codeplex
  • Download the IIS Smooth Streaming Client 1.5
  • Reference the assemblies
  • Place the player on your page

It’s that simple!

However, there are a couple of gotcha’s that I ran into while using this player;

MEF

It uses MEF to discover plugins that you may have distributed in your XAP file. That’s awesome, but if one if your assemblies contains an error (in my case the Silverlight 4 version of HTMLAgilityPack) it stops working. This is frustrating, because I did not think to look at other assemblies then the assemblies of the player framework. Took me some time to figure it out.

Fast Resume

With the Mango release of Windows Phone 7 it is possible to implement fast resume. I ran into a curious bug, feature or a bad implementation from my side when I tried to fast resume a video. It would not start playing the video and pressing the play button gives an unhandled exception.

I ended up implementing the following code, because I have no idea what is going on and no clue how to solve the issue.

namespace Channel9.Views
{
    public partial class PlayerView : PhoneApplicationPage
    {
        private bool isInitialized = false;
        private int refreshCount = 0;

        public PlayerView()
        {
            InitializeComponent();
            isInitialized = true;
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            var entry = NavigationService.BackStack.FirstOrDefault();
            if (entry != null && entry.Source.ToString().Contains("PlayerView.xaml"))
            {
                NavigationService.RemoveBackEntry();
            }
            if</span> (!isInitialized)
            {
                refreshCount++;
                NavigationService.RemoveBackEntry();
                NavigationService.Navigate(new Uri(String.Format("/Views/PlayerView.xaml?refresh={0}", refreshCount), UriKind.RelativeOrAbsolute));
            }
            isInitialized = false;
        }
    }
}

If any of my reader(s) (hi Panfilov!) knows how to solve the issue, please leave a comment.

Next time, I will post an update to the HTMLTextBlock and dive into the DelayLoadImageWithCachingControl (might be filed under a different name).

HTML TextBlock

•March 5, 2012 • 50 Comments

On the web, HTML is king. So when we create applications on the Windows Phone 7 that presents content from the web, we are bound to run into the HTML obstacle.

In this post I will dig into the ways in wich you can present HTML on the Windows Phone 7 and offer you an alternative.

Consider the HTML version of my previous post;

 <p>So it has come to this, I’ve started a blog. Let me start off by introducing myself;</p> <p>I am Matthijs Krempel a part time Windows Phone 7 developer, full time .Net developer and life time father of two boys.</p> <p>With this blog I want to share the challenges and solutions of my development journeys on the Windows Phone 7 platform. The last year I have been developing the <a title=”Channel9 Client for Windows Phone 7″ href=”http://www.windowsphone.com/en-US/apps/7551da0c-bd88-e011-986b-78e7d1fa76f8” target=”_blank”>Channel9 Client for Windows Phone 7</a> and have developed some solutions to challenges that I think and hope you will find interesting.</p> <p>I will host all code on <a title=”Krempel’s codeplex project” href=”http://krempelwp7.codeplex.com/”>codeplex </a>and link to it from here. In my next post I will go into details about the HTML Textblock.</p> <br />

The good, the bad and the ugly

Say you want to use this content in an Windows Phone 7 application. A solution is to use the standard WebBrowser control.

You can navigate to HTML from an URI or from a string. Let’s Navigate to this HTML from string, this is what the end result looks like;

It’s a start, with some additional Html formatting (solution via Ben Geek);

That’s more like it! We can now present any HTML in the native style of the phone! However, it’s not all dandy.

The huge drawback in using the webbrowser control is that it handles gestures for it’s internal scrolling and zooming. This means that if you host this control in a scrollable region, it will capture the gestures and not scroll the parent container. There are solutions in wich you can disable vertical or horizontal scrolling by drilling into the Visual Tree, but the gesture will still not availible outside the webbrowser control. The user will not be able to navigate. The tradeoff could be that you can use the webbrowser control in a standalone page, like many news readers do.

So, you are limited in your options for using the webbrowser control to present HTML content, if you are not willing to sacrifice usability.

The alternative

With Windows Phone 7.1 (Mango) a new control was added to the standard library; the RichTextBox. The RichTextBox enables us to present (a subset of) flowdocument elements, natively.

Only three obstacles left to conquer;

  1. We have HTML and we would like RichTextBox XAML
  2. Length of the XAML must not exceed 1500 (or so) characters
  3. Height of the RichTextBox must be smaller then 2000 pixels (2000×2000 is the maximum size of any Windows Phone 7 visual element)

HTML Agility Pack

I’ve solved the first problem by using the HTML Agility Pack. There is a Windows Phone 7 version availible on codeplex, download the source, open the Trunk/HAPPhone.7.1 solution, add reference to System.Xml.XPath from the Silverlight 4.0 SDK, remove build scripts and compile!  Now we have a effiecient way of navigating trough the HTML, all we have to do is translate the HTML to XAML objects. That solves obstacle 1.

We are left with two obstacles, 2 and 3. Wich we can solve quite easily. Instead of trying to create one huge RichTextBox with all the HTML in it, we create a whole host of RichTextBoxes. What I’ve done in the solution is to make a RichTextBox per paragraph. As long as the author of the comment or article refrains from using lenghty texts, we will be fine.

The end result looks something like;

You can host this HTMLTextBlock in any kind of scrollable container and the gestures work!

Source code and this example is available here!

The main goal of this control is to render the kind of HTML seen in blogs and comments, it’s not ment as a full blown browser, if you want those kinds of features fallback to the webbrowser control.

UPDATE;

New version is availible here!

 
Follow

Get every new post delivered to your Inbox.