Motivação

Uma necessidade comum na hora de exibir mensagens para o usuário é apresentar opções personalizadas, além dos botões padrão de Ok, Fechar e semelhantes. Vejamos um exemplo prático na Plataforma Universal do Windows (que vamos chamar somente de UWP).

Saiba mais sobre a Plataforma Universal do Windows

Passo 1: Mensagens básicas

Exibimos mensagens na UWP através da classe MessageDialog. Em sua forma mais básica, a classe MessageDialog recebe em seu construtor apenas a string de conteúdo, como no código a seguir. Nesse caso, a caixa de diálogo não possuirá título e irá conter apenas um botão Close.

MessageDialog mensagem = new MessageDialog("Conteúdo da mensagem");
await mensagem.ShowAsync();

O resultado é mostrado na Figura 1.

Para adicionar o título na caixa de diálogo, basta informá-lo como segundo parâmetro no construtor da classe:

MessageDialog mensagem = new MessageDialog(
    "Conteúdo da mensagem", "Título da mensagem");

Agora o resultado será o da Figura 2.

Passo 2: Botões customizados

A Listagem 1 mostra como adicionar três opções novas, cada uma com um id distinto, e ler seu resultado em um bloco switch.

01 MessageDialog mensagem = new MessageDialog("Escolha uma opção.");
02 
03 mensagem.Commands.Add(new UICommand("Sim") { Id = "S" });
04 mensagem.Commands.Add(new UICommand("Não") { Id = "N" });
05 mensagem.Commands.Add(new UICommand("Talvez") { Id = "T" });
06 
07 var resposta = await mensagem.ShowAsync();
08 
09 switch (resposta.Id.ToString())
10 {
11     case "S": //Usário clicou Sim
12         break;
13     case "N": //Usário clicou Não
14         break;
15     case "T": //Usário clicou Talvez
16         break;
17 }

Listagem 1. Mensagem com opções customizadas.

Linhas 3 a 5: adicionamos aos comandos da mensagem três objetos do tipo UICommand, cada um com um texto e um id.

Linha 7: lemos a opção selecionada pelo usuário através do método ShowAsync, cujo retorno é um objeto do tipo IUICommand.

Linhas 9 a 17: Utilizamos a opção selecionada para realizar algum procedimento customizado.

Quando exibida, essa mensagem terá a forma ilustrada na Figura 3.

Passo 3: Callbacks customizados

No exemplo anterior cada opção tinha um id, a partir do qual tomava-se uma decisão sobre qual ação realizar de acordo com a resposta do usuário. Para este tipo de cenário, também podemos atribuir essa ação customizada diretamente ao comando, podendo inclusive reaproveitá-lo posteriormente.

A classe UICommand possui uma propriedade chamada Invoked, do tipo UICommandInvokedHandler, um delegate para uma função que é executada quando o comando é acionado. Na Listagem 2 vemos como utilizá-la.

Saiba mais sobre Delegate em .NET

Note que agora não é mais necessário tratar a escolha do usuário por meio de um switch, pois cada comando (botão) contém internamente o método que será executado quando ele for acionado. Neste caso, além da preferência do programador, cabe avaliar a possibilidade de reaproveitamento de um comando em outras mensagens.

01 MessageDialog mensagem = new MessageDialog("Escolha uma opção.");
02 
03 UICommand comandoAceitar = new UICommand(
04     "Aceitar",
05     (cmd) =>
06     {
08         //Usuário clicou em Aceitar. Fazer algum procedimento adicional.   
08     },
09     0);
10 mensagem.Commands.Add(comandoAceitar);
11 
12 UICommand comandoRejeitar = new UICommand(
13     "Rejeitar",
14     (cmd) =>
15     {
16         //Usuário clicou em Rejeitar. Fazer algum procedimento adicional.   
17     },
18     1);
19 mensagem.Commands.Add(comandoRejeitar);
20 
21 await mensagem.ShowAsync();

Listagem 2. Comandos com call-back customizado

Linhas 3 a 9: Criamos um novo UICommand, passando em seu construtor seu texto (linha 4), um método anônimo que será executado quando o comando for acionado (linhas 6 a 8) e seu id (linha 9).
O argumento cmd na linha 5 representa o próprio comando que está invocando esse método. Com este argumento pode-se acessar, por exemplo, as propriedades Id e Label do UICommand. Neste caso, o cmd irá referenciar o próprio comandoAceitar.

Linha 10: Adicionamos o comando criado à mensagem.

Linha 12 a 19: funcionam da mesma forma, criando um novo comando.

A assinatura do delegate UICommandInvokedHandler é a seguinte:

public delegate void UICommandInvokedHandler(
  IUICommand command
)

Assim, qualquer método que atenda a essa assinatura pode ser atribuído à propriedade Invoked dos UICommands. Por exemplo, a Listagem 3 mostra um método desse tipo:

private void TratarBotaoAceitar(IUICommand comando)
{
    //usuário clicou em Aceitar
}

Listagem 3. Método para tratar o acionamento do comando

Agora, para utilizá-lo no lugar do método anônimo bastaria fazer como na Listagem 4.

UICommand comandoAceitar = new UICommand(
    "Aceitar",
    TratarBotaoAceitar,
    0);

Listagem 4. Utilizando o método criado no UICommand

Dessa forma, se for preciso, será possível utilizar um mesmo método para tratar as respostas do usuário em várias mensagens.