As most developers, my first test with a new technology begins with the good old “Hello World” sample and the same happened when I started digging into Metro/WinRT SDK, and you can imagine my face when I discovered that MessageBox class is no longer there.
After a few second of panic :-) I placed a search on SDK and (relief) found that its indeed alive and kicking (even in a different form) inside Windows.UI.Popups namespace with a brand new name: MessageDialog

So I started writing my first WinRT MessageDialog using this code:

private  void OnMessage(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("Hello WinRT");
dialog.ShowAsync();
}

and nothing happened! :-O
The reason is evident from the Async term appended to Show method: In WinRT any method that takes more that 50 milliseconds to complete is exposed as an asyncronous operation, in .NET this means that ShowAsync return an awaitable operation that must be explicitly started.
Let’s try again opening a MessageDialog and trying executing some code after dialog closes, what we need to write is more or less something like:

private  void OnMessage(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("Hello WinRT");
MessageDialogAsyncOperation operation= dialog.ShowAsync();
operation.Completed = new AsyncOperationCompletedHandler<IUICommand>(this.OnDialogCompleted);
operation.Start();
}

private void OnDialogCompleted(IAsyncOperation<IUICommand> asyncInfo)
{
Debug.WriteLine("Dialog closed");
}

and finally yes! dialog is here:

image

but.. do I really need to write all this code to show a dialog and continuing doing something after user dismissed it? luckily no, thanks to C# 5.0 async and await keyworks previous code can be rewritten to:

private  async void OnMessage(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("Hello WinRT");
await dialog.ShowAsync();
Debug.WriteLine("Dialog closed");
}

far better now isn’t it? ;-) note the presence of async keywork on OnMessage signature and the use of await keyword before ShowAsync() invocation

Is this all about MessageDialog? no, you can add up to 3 custom buttons to the dialog adding UICommand instances to dialog’s Commands property, each UICommand together with the text to display has the callback to invoke when related button is pushed, we can obviously use the same handler and detect the operation to execute inspecting command’s Id property, here’s a sample:

private  async void OnMessage(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("Hello WinRT");
UICommandInvokedHandler cmdHandler = new UICommandInvokedHandler(cmd =>
{
Debug.WriteLine("id:{0} label:{1}", cmd.Id, cmd.Label);
});

UICommand cmd1 = new UICommand("Cmd1", cmdHandler, 1);
UICommand cmd2 = new UICommand("Cmd2", cmdHandler, 2);
UICommand cmd3 = new UICommand("Cmd3", (cmd) =>
{
Debug.WriteLine("Command3 done!");
}, 3);

dialog.Commands.Add(cmd1);
dialog.Commands.Add(cmd2);
dialog.Commands.Add(cmd3);
dialog.DefaultCommandIndex = 1;

await dialog.ShowAsync();
Debug.WriteLine("Dialog closed");
}

In this snippet, cmd1 and cmd2 share the same handler, while cmd3 has a dedicated one while dialogo’s default button is selected via DefaultCommandIndex property.

Very powerful and flexible, glad to have it in Metro development!

Technorati Tags: ,,