New Opportunity with Marker Metro

Posted Thursday, March 22, 2012 by

From next month I'm happy to announce I'll be taking a full time role as a Senior Metro Developer at Marker Metro, an award winning Metro agency behind apps such as the incredibly popular Alphajax for Windows Phone. With Ben Gracewood also joining I'll have the privilege of working with a lot of highly skilled designers and developers on a lot of things I can't talk about yet. So stay tuned to the Marker Metro website and our respective Twitter feeds.

It's going to be a change moving back to full time employment from contract / freelance, not having to worry about invoices or taxes as much. But I'll be continuing with my Windows Phone apps and tutorials and will still be expanding the website into Windows 8 Metro apps and tutorials. More in the coming months!

Image Placeholder Control with Arbitrary Content

Posted Tuesday, February 28, 2012 by

For any application that's displaying remote images having a backup placeholder content is necessary for a polished user experience for all the times where the user has a slow internet connection, or none at all.

One possible solution from Marker Metro use Caliburn Micro and defines a behavior in order to handle failed image requests to place a placeholder image, this solution doesn't handle displaying any content before the image is loaded. David Ansom from Microsoft has created a Placeholder Image control that lets you define an image to display before the remote image is loaded and if the image is loaded.

One requirement I had was not to just display an image has a placeholder but arbitrary xaml content. What we really want to create is a marriage of Content Control and Image where we display the Content until the Image loads or if the Image fails. Since Image is a sealed control we'll create a new control based off the Content Control. This gives up the properties Content and Content Template, we'll need to add the Image properties we need Source and Stretch.

public class PlaceholderImage : ContentControl

{

    public static readonly DependencyProperty SourceProperty =

        DependencyProperty.Register("Source", typeof(ImageSource), typeof(PlaceholderImage), new PropertyMetadata(OnSourceChanged));

 

    public static readonly DependencyProperty StretchProperty =

        DependencyProperty.Register("Stretch", typeof(Stretch), typeof(PlaceholderImage), null);

 

    public PlaceholderImage()

    {

        DefaultStyleKey = typeof(PlaceholderImage);

    }

 

    public ImageSource Source

    {

        get { return (ImageSource)GetValue(SourceProperty); }

        set { SetValue(SourceProperty, value); }

    }

 

    public Stretch Stretch

    {

        get { return (Stretch)GetValue(StretchProperty); }

        set { SetValue(StretchProperty, value); }

    }

 

    ...

}

I want to use the Visual State Manager in this control to be able to have an animated transition from the content to the image; our initial state will be "Content" so we'll transition to that state in the override of OnApplyTemplate.

public override void OnApplyTemplate()

{

    base.OnApplyTemplate();

 

    VisualStateManager.GoToState(this, "Content", false);

}

In our handler for the Source property changing I follow what seems to be a standard pattern that the static method calls into a similar non static method on the control. Given this callback will be called when the image changes we’ll first make sure we’re in the Content state, we then remove our image opened handler from the previous image and add it to the new image. Once the image is loaded we’ll shift to the Image state making sure we use transitions.

private void OnSourceChanged(ImageSource oldValue, ImageSource newValue)

{

    VisualStateManager.GoToState(this, "Content", false);

 

    var oldBitmapSource = oldValue as BitmapImage;

    var newBitmapSource = newValue as BitmapImage;

 

    if(oldBitmapSource != null)

    {

        oldBitmapSource.ImageOpened -= OnImageOpened;

    }

 

    if(newBitmapSource != null)

    {

        newBitmapSource.ImageOpened += OnImageOpened;

    }

}

 

private void OnImageOpened(object sender, EventArgs e)

{

    VisualStateManager.GoToState(this, "Image", true);

}

 

private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

{

    var placeholderImage = (PlaceholderImage)d;

 

    placeholderImage.OnSourceChanged((ImageSource)e.OldValue, (ImageSource)e.NewValue);

}

That’s it for code, very simple; however some of the magic lives the Style for the control in Generic.xaml. This defines the Visual States and the animation between them, in this case we’ll fade the image in.

<Style TargetType="controls:PlaceholderImage">

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="controls:PlaceholderImage">

                <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Margin="{TemplateBinding Margin}">

                    <VisualStateManager.VisualStateGroups>

                        <VisualStateGroup x:Name="ContentStates">

                            <VisualStateGroup.Transitions>

                                <VisualTransition GeneratedDuration="0:0:1.0">

                                    <VisualTransition.GeneratedEasingFunction>

                                        <ExponentialEase EasingMode="EaseInOut" Exponent="6"/>

                                    </VisualTransition.GeneratedEasingFunction>

                                </VisualTransition>

                            </VisualStateGroup.Transitions>

                            <VisualState x:Name="Content" />

                            <VisualState x:Name="Image">

                                <Storyboard>

                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ImageContent" d:IsOptimized="True"/>

                                </Storyboard>

                            </VisualState>

                        </VisualStateGroup>

                    </VisualStateManager.VisualStateGroups>

                    <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" />

                    <Image x:Name="ImageContent" Source="{TemplateBinding Source}" Stretch="{TemplateBinding Stretch}" Opacity="0" />

                </Grid>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

The usage of the control is pretty simple, any content declared inside the control is used as placeholder content.

<controls:PlaceholderImage Source="{Binding Product.ThumbUrl, Converter={StaticResource BitmapImage}}" HorizontalAlignment="Center">

    <TextBlock Text="Loading"/>

</controls:PlaceholderImage>

I've included the code for this in the Compiled Experience Phone Toolkit I'm putting together so you can download it and use within your apps. Take a look and let me know how it can be improved.

New Tutorials Series

Posted Tuesday, February 21, 2012 by

Today I'm proud to announce the start of a new tutorial series Building a Marketplace Ready App. The goal of this series is rather than covering the basics about putting together an application, but rather the large amount of work that's required to take a sample style piece of code and getting it into a shape ready for publication. The first tutorial covering Setup and Product Search has just been posted.

The other goal with series to help me compile a lot of the disparate utilities I've used to create applications and bring them together into a single package, the 0.1 version you can download from Nuget or browse the code on Bitbucket.

Take a look and read and let me know what you think.

Help my app has been revoked!

Posted Monday, November 21, 2011 by

A couple of days ago I got a really nasty surprise, I went to open To Do Today to add something to remember to do later that day and was shocked to see the message "To Do Today has been revoked by Microsoft, please uninstall this app". Wondering what sort of rule I had broken to have this happen to me I raced to my email and saw that I'd received nothing from Microsoft. Browsing the marketplace on the phone and the web showed that To Do Today still looked like it was certified and available for purchase.

The shoe dropped when I tried to open Left to Spend and received the same message. Since I'd developed both of these apps neither was actually purchased through the marketplace, they had been side-loaded on to the phone. I quickly checked my Marketplace account and verified that my phone was still listed as "developer unlocked", but to test this I decided to redeploy the app to the phone. Surprisingly this failed with an error message informing me that my phone was not developer unlocked.

Pulling open the developer unlock tool I retried unlocking the phone to no effect. The solution ultimately involved deregistering the phone against my account and then registering it again. As soon as the phone was registered all previously failing apps loaded successfully.

My advice if you see this message is "don’t panic", especially if you haven't received any notifications from Microsoft. Most likely you've run into some weird issue like this.

Page 1 of 1012345>

Professional Windows App Development