WP7 – Testable Touch with MVVM

I have been working on my second application for the last two weeks and wanted to share some code.  As stated before, I’m really enjoying the MVVM pattern and how it makes code more testable.  I wasn’t sure that I would be able to test touch interaction with the phone but was able to work it out.

Windows Phone 7 has the same touch hooks as Silverlight 3, as far as I can tell.  You simply, add an event handler for the Touch.FrameReported event in the constructor of your page code-behind.

public myPage()
{
InitializeComponent();

Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
}

private void Touch_FrameReported(object sender, TouchFrameEventArgs e) { … }

The TouchFrameEventArgs gives you all the current touch points uniquely identified by id (in order of touch) along with their position, size and action (up, down or move).

I used the MVVM Light Messenger to pass this info along to my ViewModel but first I had to convert the touch points from the closed System.Windows.Input.TouchPoint and System.Windows.TouchDevice classes to my own open classes.  These system classes are not easily instantiated which makes testing much more difficult.  My classes mimic the others in name and structure but allow setting of any properties.

private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
IList<OpenTouchPoint> points = e.GetTouchPoints(null).Select(tp => new OpenTouchPoint(tp)).ToList();

Messenger.Default.Send(new NotificationMessage<IList<OpenTouchPoint>>(points, string.Empty));

}

I register this message in my ViewModel and assign an action to it.  I’m using a dictionary of actions by TouchAction type (up, down, move).

Messenger.Default.Register<NotificationMessage<IList<OpenTouchPoint>>>(this, message =>
message.Content.ForEach(touchPoint => _touchActions[touchPoint.Action](this, touchPoint)));

To test this I simply send a message from my unit test and then assert on the ViewModel properties.

_testTouchPoints = new List<OpenTouchPoint>
{
new OpenTouchPoint {Action = TouchAction.Move, TouchDevice = _touchDevice, Position = _newPoint}
};

Messenger.Default.Send(new NotificationMessage<IList<OpenTouchPoint>>(_testTouchPoints, string.Empty));

I was a little worried that all this code for getting touch points would slow down performance but I am getting and using four simultaneous touch points with very little lag.  WP7 supports up to 10 touch points.  I’ll be interested to see how it performs with ten at a time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s