Page 2 of 2
There is a final way in which the Metro environment is different from the Desktop. To make it more suitable for use with lower powered mobile devices, the API is mostly asynchronous. If a task takes any time at all then it will be delivered to you as an asynchronous call. Unlike other APIs, you don't get a choice in this. Most APIs provide a synchronous version of a method and perhaps an asynchronous one. The argument goes that if Metro did this you would simply take the easy way out and use the synchronous call. This would work in your development version, but in production it would eventually hold everything up. So Metro forces you to be asynchronous from the word go.
The good news is that in the .NET languages asynchronous calls are easy because of the await command introduced as part of .NET 4.5. You can find more general information in the article: Async, Await and the UI problem.
The Metro Messagebox
As an example of how the asynchronous calls work, let's take a look at the Metro version of the message box. This is one of the few pop-up windows that are available to you if you are trying to build a Metro app. In fact, it is arguable that you shouldn't really need anything like a message box if you are trying to stick to Metro style, but it is a good example and sometimes useful.
The Metro MessageDialog box lives in Window.UI.Popups so you need to add:
If you now place button on the page and move to its click event handler, you can make a MessageDialog box pop up with your message to the user. First, you need to add the keyword async to the click event handler. Any method that is going to use the await keyword has to declare itself async:
async private void Button1_Click(
object sender, RoutedEventArgs e)
Next you can create a MessageDialog box:
MessageDialog msg=new MessageDialog(
"My Message","My MessageDialog Box");
The first string is the content of the MessageDialog and the second is its title.
Now we can display the dialog box and wait while the user considers what to do:
Notice that while the click event handler appears to wait for ShowAsync to complete, just as if it was a synchronous call, the thread of execution is free to get on with something else while the dialog box is displayed - this does not freeze the UI or the machine.
When you click the Close button the program continues to execute after the await instruction, just like a synchronous call.
The MessageDialog box can display up to three commands in its command bar. If you don't specify any then you just get the Close command, and this is also the default. Setting up new commands is an interesting exercise in asynchornous programming in its own right and the same methods apply to building a pop-up right- context menu, so it is worth knowing how to do it.
When you add a command to the MessageDialog box you have to specify a command invoked handler that will be used to process the command - think of it as the command's "click" event handler if you like. When the user clicks any of the command buttons displayed the MessageDialog box closes and returns an object that contains data about which button was clicked - the id of the command, the title of the command and a delegate to the command invoked handler. Notice that you can use one of two patterns here. You can specify a single command invoked handler and let it work out which command was selected or you can specify a different command invoked handler for each command - it's up to you.
For simplicity let's just define a single command invoked handler:
var MyAction=new UICommandInvokedHandler(
Here we use a lambda expression to create a delegate of the correct type. You can create the delegate many different ways, but this one is compact.
The handler simply retrieves the label of the command that caused the event. In a real handler you would work out which command occurred and then do whatever was needed to implement the command.
Now we have a handler we can define some commands:
Now if you run the program again the MessageDialog box will have three buttons with the labels you specified. The command constructor can also be used to specify id numbers for the commands. When the user clicks on a button the MyAction event handler is called before the await returns control to the subsequent instructions.
Suppose you also want to know what the user selected in the main UI thread, i.e. after the await is completed.
The solution to this problem is that ShowAsync returns a MessageDialogAsyncOperation object, which has details of the which command has been carried out. You can obtain this object using:
var command= await msg.ShowAsync();
You need to keep in mind that this indicates which command has already been obeyed.
What more is there to learn?
You will have to find out about the dark corners of the UI framework, but as already explained it is a lot like programming for Windows Phone 7 using Silverlight. There are two final extras you need to master. The first is the life cycle of the app. As you may have noticed there is no close box or terminate button for a Metro app. They just hang around until the system decides that the user doesn't want them, when they are retired. The second topic is related in that you need to implement any long running task as a background task that can run when your foreground app is suspended.
More about Metro apps in future articles.
If you would like to be informed about new articles on I Programmer you can follow us on Twitter or Facebook or you can subscribe to our weekly newsletter.