Sunday, December 26, 2010

Extend ViewModelLocator to be a bit more dynamic

I've been using MVVM Light in my Windows Phone development. It's lightweight, has all the base functionality I need and seems pretty solid.

One pattern that MVVM Light uses is a static ViewModelLocator class that holds all of the main/root view models in the application. You declare it as a data source in the app.xaml:
<vm:ViewModelLocator d:isdatasource="True" x:key="Locator"/>

Then in the page Xaml you can do:
DataContext="{Binding Main, Source={StaticResource Locator}}"

This is great when there is basically a 1:1 mapping between the page and the contents of each view model. What it's not so good at is dealing with the situation where you want the same page to bind to multiple view models are structurally equivalent but have different data contents.

Take for instance an RSS viewer (which coincidentally enough I'm working on at the moment). You might have a feed that represents articles form a website and another feed that is discussion posts from the same website. Each feed is further broken down into topic channels. So if we wanted to display each feed as a page, with each topic as a Pivot Item on that page we could distill the page xaml down to:
<controls:Pivot Title="{Binding Name}" 
   ItemsSource="{Binding Topics}" 
   ItemTemplate="{StaticResource RssTopicTemplate}"/>
Now if the ViewModel is statically linked to the page (as above) we need to parametrize the ViewModel as the user navigates from articles to discussions and back. It can be made to work but it violates the Single Responsibility Principle and I just don't like it.

So rather than parameterizing the ViewModel how about we parametrize the page? Let's declare the linkage between ViewModel in page on the ViewModel. We'll declare an attribute that specifies the linkage and allows a parameter to be passed the page in the form of a query string.
[Page("/RssPage.xaml?vm=ArticlesStatic")]
public class ArticlesViewModel : ViewModelBase

...

[Page("/RssPage.xaml?vm=ForumsStatic")]
public class ForumsViewModel : ViewModelBase

In this app the set of navigable items are collections of viewmodels that are displayed in ListBoxes wherein each ViewModel can be selected and navigated to:
public class ContentsViewModel : ViewModelBase
{
   public ObservableCollection<ViewModelBase> Contents 
             { get; private set; }
   public RelayCommand<object> SelectViewModel 
             { get; private set; }

   private void Select(object vm)
   {
      if (vm != null)
      {
         var page = vm.GetType().GetAttribute<PageAttribute>();
         Navigate(page.Page);
      }
   }
}
Then we need a wee bit of code in the page codebehind:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (NavigationContext.QueryString.ContainsKey("vm"))
    {
        string key = NavigationContext.QueryString["vm"];
        DataContext = ViewModelLocator.FindViewModel(key);
    }
    base.OnNavigatedTo(e);
}
where FindViewModel is a method added to the ViewModelLocator that returns the correct ViewModel using reflection:
public static object FindViewModel(string key)
{
    var prop = typeof(ViewModelLocator).GetProperty(key, 
              BindingFlags.Public | BindingFlags.Static);

    return prop.GetValue(null, null);
}

I find that moving the linkage between View and ViewModel onto the ViewModel gives us the flexibility to reuse the same UI to display the contents of multiple, structurally equivalent ViewModels, while still maintaining a loose coupling between those two layers.

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.

Wednesday, October 13, 2010

I'm actually getting excited for Windows Phone 7

I've always been a nerd for mobile devices. I buy new phones more often than is wise; mostly just to see the latest technology. For years I had Windows Mobile based phones and even convinced myself that I liked them. The HTC Touch (WM 6) almost bordered on not sucking, but deep down I knew that Windows Mobile was slow, clunky and had the worst of the two worlds of PDA and Phone. I even had a WM SmartPhone once but don't get me started (I never did buy a SmartWatch though).
Finally, a year or so ago, after the umpteenth hard-rest to get my Window Mobile device to actually work as a phone again, I gave up and bought a BlackBerry. It's worked but I've never really liked it.
But now Windows Phone 7 has launched. And I gotta say it looks cool. No more Windows 95 trying to be a mobile OS. And it looks interestingly enough different from iOS and Android to have me curious. Plus I have a reasonable chance of being able to jump start some app development without having to learn the Eclipse/Java/Android stack and there's no way in hell I'll have the time to figure out to develop on a Mac with Objective C.
I've got the SDK and have already whipped up a quick app. Now all I need is a new phone.
The temptation is killing me. It's probably a foregone conclusion at this point.

Sunday, June 13, 2010

Reading iTunes m4a tags with .net

So it turns out that if you need some code to read media information out of an m4a file the only viable option to be found on the interwebs is a project called Atomic Parsley. Written in C/C++, you can tell a lot of time was put into reverse engineering the structure of MPG-4 audio file meta data and specifically, the types of tags used by iTunes.

The downside to that set of code is that it is written as a command line utility (global state, lots of fprintf, and exit(1) for error handling) and not at all structured in a way to be easily used as a class or component; especially from managed code.

Since what I have been looking for is some code that can be used from C#, I took the pieces of Atomic Parsley that I needed and restructured them as C++ classes. From there it wasn't too hard to create a C++/CLI wrapper for easy consumption in C#.

On the nostalgia side: It has been a long time since I've seen calls to malloc and I even forgot for second that unmanaged memory needs to be manually initialized to NULL.

And on the new technology side: this was a good foray into the latest C++/Cli syntax, using VS.NET 2010 and .NET4. It's getting more and more like C# in flavor but is still feels cumbersome in comparison. That being said, when creating a shiny new managed interface around legacy code, it cannot be beat.

So if you are looking for a mechanism to read meta-data from iTunes/m4a files the result might be helpful. Check it out on google code.

Monday, April 5, 2010

A new CodeProject article

A while back I came across a fun bit of code on CodeProject that used alpha blending to animate a fish swimming around on the screen. I've been toying around with that code on and off for awhile and it finally has turned into a whole bunch of fish swimming around on the screen.

If you've been dieing to have fish swimming around on your screen the wait is over. Check it out over at CodeProject.

(This is written against the .NET 4 RC. You may need to download this for it to work.)

Sunday, February 21, 2010

Dynamically evaluating a JOIN expression with Linq

For the last little while I've been toying around with System.Linq.Expressions and a mini SQL parser to see how far I can go with evaluating plain text SQL expressions against arbitrary collections of objects. It's mostly a side project for my own enjoyment but eventually I am hoping it actually turns into something broadly useful.

Results so far I've put on CodeProject:
It's been awhile but today I opened up that code again and got a basic JOIN operator working. This is cool because ultimately I'd like to be able to join loosely related datasources; say across the mp3 tags in my music collection and the data on my last.fm account.

So just now I've been able to get this unit test to pass:
[TestMethod]
public void SimpleJoin()
{
    IEnumerable source<Person> = TestData.GetPeople();
    IEnumerable families<Family> = TestData.GetFamilies();

    var answer = source.Join(families, p => p.Address, f => f.Address,
        (p, f) => new FamilyMember { Name = p.Name, LastName = f.Name, Location = f.Address });

    var result = source.Query<Person, Family, FamilyMember>
              ("SELECT Name, that.Name AS LastName, Address AS Location 
              FROM this INNER JOIN that ON this.Address = that.Address", families);

    Assert.IsTrue(result.SequenceEqual(answer));
}

This is cool because now I can start generating complex queries without having compile time knowledge of the underlying data structures. Once I get things fleshed out further I'll update things on CodeProject.

Monday, February 15, 2010

A new CodeProject article

I always like  to use System.Diagnostics.Trace to report detailed status to the user. For the longest time I used a handy little WinForms control that inherited from TextBox to do that. Well now that I am hiking up the WPF learning curve I need a new version.

Said version is posted on Codeproject. Check it out if you need such a thing.

Sunday, February 7, 2010

C# Property class Part 2

Commenter tonyt (from CodeProject) rightly points out that there are drawbacks to this approach: A C# Property Class.
Why:

Because there is a mountain of core functionalty in .NET that relies heavily on things like property access via reflection (like data binding) and via System.ComponentModel (e.g., TypeDescriptor), none of which support your take on implementing properties.

You can implement INotifyPropertyChanged on any class that offers a more efficient way to get notified about property changes, as it requires only one delegate for each listener, regardless of how many supported properties you have.

He's right. But I still want to explore this approach. What if we take the Property class and have it implement INotifyPropertyChanged?
public class Property<T> : INotifyPropertyChanged
{
    protected T _value = default(T);

    public Property()
    {
    }

    public Property(T value)
    {
        _value = value;
    }

    public event EventHandler Changed;

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual T Value
    {
        get { return _value; }
        set
        {
            if ((value != null && !value.Equals(_value)) ||
                (_value != null && !_value.Equals(value)))
            {
                _value = value;
                OnChanged();                    
            }
        }
    }

    public override string ToString()
    {
        return object.ReferenceEquals(_value, null) ? string.Empty : _value.ToString();
    }

    protected virtual void OnChanged()
    {
        if (Changed != null)
            Changed(this, EventArgs.Empty);

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Value"));
    }

    public static implicit operator T(Property property)
    {
        if (property == null)
            return default(T);

        return property.Value;
    }
}

Now we can create an class like so:
class ViewModel
{
    public ViewModel()
    {
        Status = new Property<string>("");
    }

    public Property<string> Status { get; private set; }
}
Note the switch from a readonly field to a read-only property. WPF binding requires properties and does not work with fields.

And then we can bind to that in XAML like so:
<TextBox Text="{Binding Path=Status.Value}"/>
(assuming that the DataContext of the TextBox is a ViewModel like the one above.)

That should go a little way to addressing tonyt's point (mostly because WPF data binding is so robust).

Thursday, February 4, 2010

Why does Bluetooth insist on sucking so badly?

Every couple of years since I had the grand vision of owning wireless stereo headphones (which I still do not have), I purchase some bluetooth gadget marginally more complicated than a cell phone earbud in order to see if the technology has ceased to suck. So last week I bought a mini Bluetooth wireless mouse to go along with my new Netbook (yum on the netbook BTW: buy one; buy one right now).

So I get it home, unpack it and first thing first download the bluetooth drivers. 77 megs. Yes that's right 77 megabytes of driver. Oi oh well. Push forward.

Awhile and a reboot later up it comes. No findy the bluetooth radio. WTF? Oh wait gotta hotkey that to turn it on. Boink up comes Bluetooth but down goes WIFI. WTF? Hotkey, Hotkey. Bluetooth On; Wifi Off. Bluetooth Off; Wifi Off; Bluetooth off; Wifi On.

See something missing in that sequence? (this we can blame I suppose on the maker of the netbook but I think that the general suckiness of bluetooth forced it upon them)

Oh well I think. I'll come back to that later. Let's see if I can get this thing to recognize the mouse. A few pushes to the sync button on the mouse and "Installing new HID hardware..."

"Yay!" I think "Success!" Until... "Your new hardware installed successfully. Please reboot to complete the installation" Uh-oh. So dutifully I reboot; up comes the bluetooth "Let's find some hardware dialog"; push push push; hotkey hotkey hotkey. Nothing. No mouse. Under no combination of pushing and hotkeying does my netbook believe that there is a wireless mouse a mere centimeter away; crying to be recognized.

So I take the whole thing; dump it back in the bag and return it for one of the 2.4 GHz wireless jobs with the nano transceiver thingy. Pop that puppy in and and up it comes; no software install; recognizes the mouse with no intervention from me. Boop; 30 seconds; mouse.

So bluetooth has been around how long now? And it still sucks this bad? This is what happens when a technology tries to be all things to all people. I'm sure the designers of blueooth saw/see it as the last wireless technology stack ever needed. By anyone. Anywhere.

In truth it's a darn fine wireless earbud solution for your cell phone. That's about it. Perhaps I'll check back in a couple of years. In the meantime, nano-transceiver... yum.

Saturday, January 30, 2010

A C# Property class

Soon after starting work in C# there were a couple of code patterns that arose that made me miss the good ol' C/C++ pre-processor. One of these is the basic pattern of a class property with change notification.

You've got a class and you want the state of its properties to be observable via events. How many time have you written the following bit of code in some for or other?
int _age;

public event EventHandler AgeChanged;

protected virtual void OnAgeChanged()
{
  if(Changed != null)
    Changed(this, EventArgs.Empty);
}

public int Age
{
  get{ return _age; }
  set
  {
    if(value != age)
    {
      value = age;
      OnAgeChanged();
    }
  }
}
Automatic properties help when you don't need notification, INotifyPropertyChange abstracts that event a little. Still, a lot of boilerplate. Having written a fair amount of MFC in the years prior I really wanted to be able to do something like:
DECLARE_PROPERTY(Age, int)
and have a fancy macro that would handle the boiler plate. Alas there is no macro pre-processor in C#-land.

The introduction of .NET generics opens up the opportunity to model a class property as a class itself, while retaining type safety and the same assignment semantics as intrinsic types. So this little class (and a derived class with a cancellable event) has become a handy part of my toolbox.

public class Property<T>
{
  protected T _value = default(T);

  public Property()
  {
  }

  public Property(T value)
  {
    _value = value;
  }

  public event EventHandler Changed;

  public virtual T Value
  {
    get { return _value; }
    set
    {
       if ((value != null && !value.Equals(_value)) ||
          (_value != null && !_value.Equals(value)))
       {
          _value = value;
          OnChanged();
       }
    }
  }

  protected virtual void OnChanged()
  {
     if (Changed != null)
       Changed(this, EventArgs.Empty);
  }

  public static implicit operator T(Property property)
  {
    if (property == null)
      return default(T);

    return property.Value;
  }
}
using it is just a matter of declaring a public field on a class declaration.
class Person
{
  public readonly Property<int> Age = new Property<int>();

  public readonly Property<string> Name = new Property<string>();
}
Interacting with the properties looks a lot like an intrinsic:
Person don = new Person();
don.Name.Value = "Don";
don.Age.Value = 41;

if (don.Age > 40)
  Console.WriteLine("Ooooooold");
 
with the difference that every property now comes with a built in Changed event
don.Age.Changed += new EventHandler(Age_Changed);

So anyway, I've found this to be a handy helper class and thought perhaps you might as well.

PS: the cancellable derived class looks like this:
class CancellableProperty<T> : Property<T>
{
  public CancellableProperty(T value)
    : base(value)
  {
  }

  public event CancelEventHandler Changing;

  public override T Value
  {
    set
    {
      if ((value != null && !value.Equals(_value)) ||
         (_value != null && !_value.Equals(value)))
      {
        CancelEventArgs args = new CancelEventArgs(false);
        OnChanging(args);
        if (args.Cancel == false)
        {
          _value = value;
          OnChanged();
        }
      }
    }
  }

  protected virtual void OnChanging(CancelEventArgs args)
  {
    if (Changing != null)
      Changing(this, args);
  }
}