Arquivo

Textos com Etiquetas ‘Async CTP’

Utilizando ChildWindows de forma síncrona

Um problema que me deparo constantemente é a necessidade de abrir um ChildWindow qualquer e continuar a execução do código a partir do retorno deste. Claro que é possível fazer isto utilizando Actions e eventos, mas não seria muito melhor que trabalhasse de forma semelhante ao MessageBox do WinForms?

Antes de começar é necessário instalar o Visual Studio Async CTP pois ele nos da a possibilidade de trabalhar de forma Assíncrona/Síncrona.

Primeiro criaremos um novo projeto com o template Silverlight Application. Dentro do projeto crie um novo item utilizando o template ChildWindow, e de-lhe o nome de ChildWindowSync.

Criaremos então um método estático que será responsável por mostrar a nossa window conforme o código abaixo:

        public static Task<bool> ShowSync()
        {
            var tcs = new TaskCompletionSource<bool>();
            var window = new ChildWindowSync();
            window.Closed += (sender, e) => {
                tcs.TrySetResult(window.DialogResult.Value);
            };
            window.Show();
            return tcs.Task;
        }

Veja que é bastante simples, criamos um objeto TaskCompletionSource que será a task retornada quando nossa window for fechada, após este passo a janela é criada e adicionamos um eventHandler ao evento de closed. Dentro deste handler setamos o dialogResult que foi definido pelos métodos de button click do Ok e Cancel;

Neste momento seu código deve estar parecido com o abaixo:

    public partial class ChildWindowSync : ChildWindow
    {
        public ChildWindowSync()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        public static Task<bool> ShowSync()
        {
            var tcs = new TaskCompletionSource<bool>();
            var window = new ChildWindowSync();
            window.Closed += (sender, e) => {
                tcs.TrySetResult(window.DialogResult.Value);
            };
            window.Show();
            return tcs.Task;
        }
    }

Agora criaremos um botão na MainPage.xaml que irá chamar nossa ChildWindowSync.

<UserControl x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Button x:Name="testebtn" Content="Open window" Click="testebtn_Click"
                VerticalAlignment="Center" HorizontalAlignment="Center"/>
    </Grid>
</UserControl>

O async ctp exige que seja utilizado a palavra reservada “async” nos métodos que utilizam chamadas assíncronas em seu corpo. No caso a assinatura do método testbtn_Click fica da seguinte forma:

private async void testebtn_Click(object sender, RoutedEventArgs e)

então colocamos o corpo do nosso método para esperar ate que a childWindow seja fechada e retornar se o DialogResult foi True ou False

private async void testebtn_Click(object sender, RoutedEventArgs e)
        {
            bool teste = await ChildWindowSync.ShowSync();
            if (teste)
            {
                MessageBox.Show("Você Clicou em Ok!");
            }
            else
            {
                MessageBox.Show("Você clicou em Cancel!");
            }
        }

Rode a aplicação e veja o resultado. Você verá que ao clicar no nosso botão de teste a child window é exibida e o resultado é exibido somente depois da janela ter um resultado: true se for clicado em Ok e False se for clicado em Cancel ou fechar a janela pelo X.

O código fonte deste exemplo pode ser baixado aqui.

Categories: Silverlight Tags: ,