Friday, December 17, 2010

CPVanity for Windows Phone

I always kind of liked Luc Pattyn's CPVanity app that lets you check out your code project reputation and keep an eye on article ranking.

So here's a WP7 port of it as a small homage. It's up on the marketplace too.

Wednesday, December 15, 2010

Handy Windows Phone 7 resources

Now that I've gotten past the "Hello World" stage of WP7 development here are some code and resources that I've found quite helpful:

Wednesday, December 8, 2010

A helper class to get the current location on a Windows Phone just once

Getting the location on Windows Phone is done via the GeoCoordinateWatcher. The coordinate watcher has a some best practices associated with it one of which is to minimize power consumption. Once you turn this thing on its going to be using the GPS to stream location event back to your app which will hit the battery.

There are some instance where you may not a running notification of the current potion but just want the current position (for instance you may want to initialize the position on a map but not track changes to position).

So this is a small helper class that starts up the coordinate watcher asynchronously, returns the first coordinate found and then shuts it down. One could use TryStart like so:
using (var watcher =  new 
                GeoCoordinateWatcher(GeoPositionAccuracy.Default))
{
    var location = watcher.TryStart
                (false, TimeSpan.FromMilliseconds(1000));
}
but since that will block your UI thread (assuming you call it from the UI) you'd need to wrap it in some asynchronous stuff anyways.
So I use this class:
public class ImmediateLocation : IDisposable
{
    private GeoCoordinateWatcher _watcher;
    private Action<GeoCoordinate> _action;

    public ImmediateLocation(Action<GeoCoordinate> a)
    {
        Debug.Assert(a != null);

        _action = a;
    }

    public void GetLocation()
    {
        if (_watcher == null)
        {
            _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
            _watcher.MovementThreshold = 1000;

            _watcher.PositionChanged += new 
                EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>
                (_watcher_PositionChanged);
            _watcher.StatusChanged += new 
                EventHandler<GeoPositionStatusChangedEventArgs>
                (_watcher_StatusChanged);

            _watcher.Start(false);

            if (_watcher.Status == GeoPositionStatus.Disabled
                || _watcher.Permission == GeoPositionPermission.Denied)
                Dispose();
        }
    }

    void _watcher_StatusChanged(object sender, 
        GeoPositionStatusChangedEventArgs e)
    {
        if (e.Status == GeoPositionStatus.Disabled 
            || _watcher.Permission == GeoPositionPermission.Denied)
            Dispose();
    }

    void _watcher_PositionChanged(object sender, 
        GeoPositionChangedEventArgs<GeoCoordinate> e)
    {
        _action(e.Position.Location);
        Dispose();
    }

    public void Dispose()
    {
        if (_watcher != null)
        {
            _watcher.Stop();
            _watcher.PositionChanged -= new 
                EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>
                (_watcher_PositionChanged);
            _watcher.StatusChanged -= new 
                EventHandler<GeoPositionStatusChangedEventArgs>
                (_watcher_StatusChanged);
            _watcher.Dispose();
        }
        _watcher = null;
        _action = null;
    }
}

Then you can just do this:
void InitLocation()
{
     var immediate = new ImmediateLocation(x => location = x);
     immediate.GetLocation();
}

GeoCoordinate location;
It acts like a one time use, fire and forget location setter that cleans itself up when done. It does have Dispose if you want to mange the lifetime more closely.

Sunday, December 5, 2010

New CodeProject article

I just posted an article on codeproject that goes into detail on my experience building a Windows Phone 7 app. Source code included. Check it out.

Microsoft posts a nice improvement to the WP7 progress bar

Showing that your WP7 app is doing some work is as simple as adding a progress bar and setting its IsIndeterminate property to true. This will show the animating dots that glide from left to right in all the WP7 apps.

<ProgressBar IsIndeterminate="{Binding Working}"/>

The problem with the current version of the control is that it animates on the UI thread. So if your UI is doing something as well it can be kind of jerky.

MSDN has a code snippet that moves the animation to the compositor thread. I'd recommend using this approach as it has a noticeable improvement, animating nice and smoothly.

Thursday, December 2, 2010

Got a WP7 app published

There's already a Microsoft last.fm browser/player but since I like last.fm and have some experience with their API, I thought it would be a good WP7 learning tool. Plus it goes a little more in dpeth into the content.

It's published now on the app hub. So that's pretty cool.

Thursday, November 25, 2010

Lesson's learned from my first WP7 App submission

Lesson 1: Don't forget about the Light theme.
I developed the app completely using the Dark theme on my phone and the emulator. Lo and behold switch it to Light and some parts of it were unreadable, especially the ApplicationBar. My first submission was rejected because of this. Other parts just didn't all that good on the Light theme. We'll see how swing #2 goes...

Lesson 2: Don't set the ApplicationBar colors unless you really want those colors on both themes.
You can't DataBind them and they will be switched automatically per Theme by WP7, but not if you have set the colors by hand in your XAML.

Lesson 3: Don't use color icons on the ApplicationBar
Again, they may look great on the dark theme but switch to the Light theme and they will be drawn as black outlines at best, black blobs at worst. Use White on Transparent icons. They look fine on both themes. There are some good ones online. Don't include the outer circle (the app bar adds it) and set the image itself to 24x24.