Archive for November, 2010

Change the Windows Phone 7 background image for the light or dark theme

Sunday, November 28th, 2010

Windows Phone 7 applications have a better sense of presence when they have their own background image. By default, the background is white for the light theme or black for the dark theme. Using only XAML markup, we can choose either a light or dark background image instead.

Create two 480x800 images, one dark and one light. The easiest way to do this is take a photograph, scale and crop it to the right size, then adjust the contrast and brightness. For both images, you want a low contrast. For the dark image, turn down the brightness. For the light one, turn it up.

background2d  background2l

Save both as png, and add them to an Images folder in your application. Set “Build Action” to “Resource” and “Copy to Output Directory” to “Do not copy”.

image

Create two Image controls in your page’s LayoutRoot. By default, the LayoutRoot is a Grid offset 30 pixels from the top. Set the margins to 0,–30,0,0 so that the image fills the entire page. The grid has two rows by default, so set the RowSpan to 2.

image  image

Set the Source of one Image to the dark png. Set Stretch to UniformToFill. Then bind its visibility to PhoneDarkThemeVisibility. Set the Source and Stretch of the other Image, and bind its Visibility to PhoneLightThemeVisibility.

image  image

Now using the Blend Device window, switch between dark and light to make sure the result is what you expect.

image  image

This all works directly in XAML without editing code. You can use this technique for most visual aspects. But if you need to detect which theme is active in code, Magnus Johansson has instructions at Insomniac Geek.

What makes a good phone app?

Wednesday, November 24th, 2010

My head-to-head Reversi app is almost ready for the Windows Phone marketplace. I finally have it on my phone, and I am testing it rigorously.

I’ve owned an iPod Touch, an Android G1, and now a Windows Phone 7. Based on that experience and the reactions from my testers, here’s what I think makes a good phone app.

Quality

It’s hard to quantify but easy to recognize. If an app feels hacked together, I don’t want to use it. It doesn’t matter if it’s only 99 cents, or even if its free. I don’t want to reward an app developer who does not obviously care.

Purposefulness

We are used to doing work with our computers. We are actively involved in every step of the process -- clicking on menus, filling in forms, verifying results.

But a smart phone is an agent. I want to tell it what to do, and then let it do the work. If I have to go through all the steps myself, then the phone is the wrong platform.

Disconnected operation

Smart phones have many radios, so connectivity shouldn’t be a problem, right? Not so. These radios don’t work well indoors, on the road, or in large crowds. If an app needs a connection to work properly, it may as well be a web page.

Smart phones have a lot of storage. I expect my apps to use it. When I pull up IMDB, I expect that the list of movies on the front page will be similar to the ones I saw yesterday. It shouldn’t have to hit the network. Refresh the list in the background, and let me work with the information that I already have.

Discoverability

There is no instruction manual that comes with an app. A user needs to figure it out based only on the clues that it gives them.

An app should know the very next thing that the user wants to do. It should put that plainly on the screen with a meaningful icon, a natural gesture, or as a last resort text.

An app should also anticipate what the user might try. For example, if you have a Windows Phone, press the home button on the lock screen. The screen will bounce to indicate that there is something below it. The user swipes up to see what it is, thereby learning the correct unlock gesture.

Fit the platform

An iPhone app should have an icon with rounded corners and reflections. It should use the standard page animations, title, and back button showing the title of the prior page. A Windows Phone app, on the other hand, should have a flat square icon, and no on-screen back button. Pivot and panorama work on the Windows Phone. Don’t try them on Android.

The mistakes I’ve made

My Reversi game made several of these mistakes.

With respect to quality, it had some serious bugs when I started testing with other people. I had forgiven these bugs, since I know the workarounds. But others did not. Get other people to test your app.

Another quality issue was responsiveness. Initially it took a full second for the game board to appear. This confused people. So I made the game board a separate XAML element. It still takes a second for the pieces to initially appear, but at least the game board is there. It feels like a more solid app.

A final quality issue was that it was far too easy to accidentally hit the home button. I put a piece at the bottom of the board to indicate that it is your move. You drag this piece onto the board to play. Unfortunately, the piece appeared just above the home button on the physical device. My wife went to the home screen once for every 2 or 3 moves that she made.

To provide purposefulness, I give you additional information about the game. I show you not only the pieces that you are about to capture, but also the moves that you are allowing your opponent. Reversi, as it turns out, is more about moves than it is pieces. But I didn’t take purposefulness far enough. I also needed to continue showing those moves after the piece is dropped, so your opponent can easily see what’s available to him. It raises the level of abstraction.

For discoverability, I show a pulsing glow behind the new piece. People understand that this means “drag me”. But I didn’t anticipate what the user would try. Most people just try to touch the square where they want to move. Since that’s what they try, I now honor that gesture.

Disconnected operation is the one place where I focused my attention. Reversi is the inaugural Correspondence application, and Correspondence was designed for disconnected operation. Still, there were a few things that I had to fix. Most significantly, if you make a move while disconnected, it is queued on the device. Once you are connected again, you have to tell the application to send the move. The way you do that in Reversi is to return to the main screen. This is naturally what the user would do, since they can’t do anything else on the game screen.

Finally, to fit the Windows Phone platform, Reversi uses very simple flat graphics. However, the platform also calls for background images. The application feels incomplete without photography. So I’m taking pictures of real Reversi pieces to give the user the feeling of presence.

The app will be in the Marketplace after another week or two of testing.

Hands-On MVVM video

Friday, November 5th, 2010

Many thanks to Shawn Weisfeld for recording my Hands-On MVVM session at the Forth Worth .NET User’s Group.

A non-relational database for Windows Phone 7

Monday, November 1st, 2010

The Windows Phone 7 development platform shipped with no built-in database. This is a surprising departure from Windows CE and Windows Mobile, both of which had on-device database support. Several open-source relational database projects are currently porting their codebases. But perhaps this is a good time to reevaluate the needs of the platform. Do you really want a relational database on a phone?

Correspondence is a non-relational database for occasionally-connected clients. The new build of Correspondence has project templates for Windows Phone 7. It is a natural fit for the platform. After all, what client is more occasionally-connected than a phone?

What can you do with a non-relational database?

Relational databases are optimized for ad-hoc queries, such as those required for data analysis and business intelligence. Relational databases are fantastic at reporting, and very efficient at processing large numbers of records. Your typical phone application requires none of these things.

There are several flavors of non-relational database (document, associative array, network, etc.) Each offers different sets of features. In general, however, non-relational databases are good at:

  • Quickly locating related entities.
  • Representing hierarchical data.
  • Searching or sorting by application-defined attributes.
  • Mapping to object-oriented code.

These are typically the features most desired by mobile application developers.

Where does Correspondence fit in?

Correspondence is a historical database. It is closely related to a network database, but with one significant difference: all entities are immutable. This is how historical databases gain their uncanny ability to synchronize.

Both historical and network databases directly connect entities with their neighbors. A phone application requires quick access to related entities. Starting at one point, the user of the application selects items to drill through a network of objects. They want the application to start up quickly, and they want the phone to be responsive. These phones generally do not have powerful processors or a great deal of memory. So a database that links entities directly to one another rather than indexing them is a win in this situation.

But historical and network databases differ in that network databases allow entities to change over time. This is the way we typically think about object-oriented systems. But historical databases do not allow entities to change. The only way to alter an entity is to append another that changes its meaning. The entity itself is immutable.

The reason for modeling data historically is to support synchronization. Things that change are hard to synchronize. Things that don’t are easy. A phone is only a small part of a person’s life. If their data was only on the device, it would be of limited value. A database that is optimized for synchronizing with the desktop and the Web is much more compelling.

How do you model changing data with immutable entities?

Consider a chess board. During the course of the game, the board position changes dramatically. We could model a chess game in an object-oriented system as an 8-by-8 grid of squares whose values change over time.

But the chess game is actually a sequence of discrete moves. Once a move is made, it cannot be changed. By observing that history of moves, we can determine the current position of the board. In fact, we can reconstruct the board position at any point in time. The mutable chess board is modeled with a sequence of immutable moves.

An application based on a historical database works the same way. Rather than capturing the current state of the system, the database captures all of the decisions that led to that state. These decisions have been made in the past, and are now considered historical facts. By querying related facts, the application can quickly determine the state of the system.

Take a contact manager application, for example. Add a person with the name “Mike”. You will have a Person fact and a Name fact.

Contacts

Now let’s change the name. We do that by introducing a new Name fact. This one not only references the Person, but also the prior name.

Contacts

We don’t have to replay all of the historical facts to determine the current name of a contact. We can quickly query a Person for the related Name that has not been replaced. In the modeling language of Correspondence, the query looks like this:

fact Person {
    unique;

    Name* currentNames {
        Name n : n.person = this
            where n.isCurrent
    }
}

fact Name {
    Person person;
    Name* prior;
    string value;

    bool isCurrent {
        not exists Name next : next.prior = this
    }
}

The currentNames query appears as a collection in code. You can make it look like a mutable property like this:

public partial class Person {
    string Name
    {
        get
        {
            return CurrentNames
                .Select(name => name.Value)
                .FirstOrDefault();
        }
        set
        {
            Community.AddFact(new Name(this, CurrentNames, value));
        }
    }
}

The getter pulls the value of the Name matching the query. The setter creates a new name. It passes CurrentNames to the new fact as the value of “prior”, thus ensuring that it replaces the current value.

What next?

Please download the latest build of Correspondence from CodePlex. On that site, you will also find some walkthroughs that take you through building your first Correspondence application in WPF. Once you are comfortable thinking historically, try it on Windows Phone 7. You can find more patterns like the one above on Historical Modeling.