Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Esta é a terceira parte de um tutorial que demonstra como modernizar um aplicativo de desktop WPF de exemplo chamado Contoso Expenses. Para obter uma visão geral do tutorial, pré-requisitos e instruções para baixar o aplicativo de exemplo, consulte Tutorial: Modernizar um aplicativo WPF. Este artigo pressupõe que você já tenha concluído parte 2.
No cenário fictício deste tutorial, a equipe de desenvolvimento da Contoso deseja facilitar a escolha da data para um relatório de despesas em um dispositivo habilitado para toque. Nesta parte do tutorial, irá adicionar um controlo UWP CalendarView à aplicação. Este é o mesmo controle que é usado na funcionalidade de data e hora do Windows na barra de tarefas.
Ao contrário do Microsoft.Toolkit.Wpf.UI.XamlHost. Este pacote está incluído no pacote NuGet Microsoft.Toolkit.Wpf.UI.Controls que você instalou na parte 2 .
Observação
Este tutorial demonstra apenas como usar WindowsXamlHost para hospedar o controle CalendarView de primeira parte fornecido pelo SDK do Windows. Para obter uma explicação passo a passo que demonstra como hospedar um controle personalizado, consulte hospedar um controle UWP personalizado em um aplicativo WPF usando Ilhas XAML.
Para usar o controle Microsoft.Windows.SDK.Contracts contém as referências necessárias para permitir que você chame APIs do WinRT a partir do aplicativo. Este pacote também está incluído no pacote NuGet Microsoft.Toolkit.Wpf.UI.Controls que você instalou na parte 2 .
Adicionar o controle WindowsXamlHost
No Gerenciador de Soluções
, expanda a pasta Modos de Exibição no projeto ContosoExpenses.Core e clique duas vezes no arquivo AddNewExpense.xaml. Este é o formulário usado para adicionar uma nova despesa à lista. Aqui está como ele aparece na versão atual do aplicativo.
O controle seletor de data incluído no WPF destina-se a computadores tradicionais com mouse e teclado. Escolher uma data com um ecrã táctil não é realmente viável, devido ao pequeno tamanho do controlo e ao espaço limitado entre cada dia no calendário.
No início do ficheiro AddNewExpense.xaml, adicione o seguinte atributo ao elemento Window.
xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"Depois de adicionar esse atributo, o elemento Window agora deve ter esta aparência.
<Window x:Class="ContosoExpenses.Views.AddNewExpense" 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" xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost" DataContext="{Binding Source={StaticResource ViewModelLocator},Path=AddNewExpenseViewModel}" xmlns:local="clr-namespace:ContosoExpenses" mc:Ignorable="d" Title="Add new expense" Height="450" Width="800" Background="{StaticResource AddNewExpenseBackground}">Altere o atributo
Height do elementoWindow de 450 para 800. Isto é necessário porque o controle UWP CalendarView ocupa mais espaço do que o seletor de data do WPF. <Window x:Class="ContosoExpenses.Views.AddNewExpense" 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" xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost" DataContext="{Binding Source={StaticResource ViewModelLocator},Path=AddNewExpenseViewModel}" xmlns:local="clr-namespace:ContosoExpenses" mc:Ignorable="d" Title="Add new expense" Height="800" Width="800" Background="{StaticResource AddNewExpenseBackground}">Localize o elemento
DatePickerperto da parte inferior do arquivo e substitua esse elemento pelo seguinte XAML.<xamlhost:WindowsXamlHost InitialTypeName="Windows.UI.Xaml.Controls.CalendarView" Grid.Column="1" Grid.Row="6" Margin="5, 0, 0, 0" x:Name="CalendarUwp" />Este XAML adiciona o controlo WindowsXamlHost. A propriedade InitialTypeName indica o nome completo do controle UWP que você deseja hospedar (neste caso, Windows.UI.Xaml.Controls.CalendarView).
Pressione F5 para criar e executar o aplicativo no depurador. Escolha um funcionário na lista e pressione o botão Adicionar nova despesa. Confirme se a página a seguir contém o novo controlo UWP CalendarView.
Feche o aplicativo.
Interagir com o controlo WindowsXamlHost
Em seguida, você atualizará o aplicativo para processar a data selecionada, exibi-la na tela e preencher o objeto Expense salvar no banco de dados.
O UWP CalendarView contém dois membros que são relevantes para este cenário:
- A propriedade SelectedDates contém a data selecionada pelo usuário.
- O evento SelectedDatesChanged é gerado quando o usuário seleciona uma data.
No entanto, o controlador WindowsXamlHost é um controlador de host genérico para qualquer tipo de controlador UWP. Como tal, ele não expõe uma propriedade chamada
No arquivo AddNewExpense.xaml, adicione um event handler para o evento ChildChanged do controle WindowsXamlHost que você adicionou anteriormente. Quando terminar, o elemento WindowsXamlHost deverá ter esta aparência.
<xamlhost:WindowsXamlHost InitialTypeName="Windows.UI.Xaml.Controls.CalendarView" Grid.Column="1" Grid.Row="6" Margin="5, 0, 0, 0" x:Name="CalendarUwp" ChildChanged="CalendarUwp_ChildChanged" />No mesmo arquivo, localize o elemento Grid.RowDefinitions do Grid principal . Adicione mais um elemento RowDefinition com a Height igual a Auto no final da lista de elementos filhos. Quando terminar, o elemento Grid.RowDefinitions deve ter este aspecto (deve haver agora 9 elementos RowDefinition).
<Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>Adicione o seguinte XAML após o elemento WindowsXamlHost e antes do elemento Button perto do final do arquivo.
<TextBlock Text="Selected date:" FontSize="16" FontWeight="Bold" Grid.Row="7" Grid.Column="0" /> <TextBlock Text="{Binding Path=Date}" FontSize="16" Grid.Row="7" Grid.Column="1" />Localize o elemento Button perto do final do ficheiro e altere a propriedade Grid.Row de 7 para 8. Isso desloca o botão para baixo uma linha na grade porque você adicionou uma nova linha.
<Button Content="Save" Grid.Row="8" Grid.Column="0" Command="{Binding Path=SaveExpenseCommand}" Margin="5, 12, 0, 0" HorizontalAlignment="Left" Width="180" />Abra o arquivo de código AddNewExpense.xaml.cs.
Adicione a seguinte instrução à parte superior do arquivo.
using Microsoft.Toolkit.Wpf.UI.XamlHost;Adicione o seguinte manipulador de eventos à classe
AddNewExpense. Este código implementa o evento ChildChanged do controlo WindowsXamlHost que declarou anteriormente no arquivo XAML.private void CalendarUwp_ChildChanged(object sender, System.EventArgs e) { WindowsXamlHost windowsXamlHost = (WindowsXamlHost)sender; Windows.UI.Xaml.Controls.CalendarView calendarView = (Windows.UI.Xaml.Controls.CalendarView)windowsXamlHost.Child; if (calendarView != null) { calendarView.SelectedDatesChanged += (obj, args) => { if (args.AddedDates.Count > 0) { Messenger.Default.Send<SelectedDateMessage>(new SelectedDateMessage(args.AddedDates[0].DateTime)); } }; } }Esse código usa a propriedade Child do controlo WindowsXamlHost para aceder ao controlo CalendarView da UWP. Em seguida, o código se inscreve no evento
SelectedDatesChanged, que é acionado quando o usuário seleciona uma data do calendário. Este manipulador de eventos passa a data selecionada para o ViewModel, onde o novo objeto de Despesas é criado e salvo no banco de dados. Para fazer isso, o código usa a infraestrutura de mensagens fornecida pelo pacote MVVM Light NuGet. O código envia uma mensagem chamada SelectedDateMessage para o ViewModel, que a receberá e definirá a propriedade Date com o valor selecionado. Nesse cenário, o controle CalendarView é configurado para o modo de seleção único, portanto, a coleção conterá apenas um elemento. Neste ponto, o projeto ainda não consegue ser compilado porque está faltando a implementação da classe SelectedDateMessage. As etapas a seguir implementam essa classe.
No Gerenciador de Soluções, clique com o botão direito do rato na pasta Mensagens e escolha Adicionar -> Classe. Nomeie a nova classe SelectedDateMessage e clique em Adicionar.
Substitua o conteúdo do arquivo de código SelectedDateMessage.cs pelo código a seguir. Esse código adiciona uma instrução using para o namespace
GalaSoft.MvvmLight.Messaging(do pacote NuGet MVVM Light), herda da classe MessageBase e adiciona a propriedade DateTime que é inicializada através do construtor público. Quando terminar, o ficheiro deverá ter o seguinte aspeto.using GalaSoft.MvvmLight.Messaging; using System; namespace ContosoExpenses.Messages { public class SelectedDateMessage: MessageBase { public DateTime SelectedDate { get; set; } public SelectedDateMessage(DateTime selectedDate) { this.SelectedDate = selectedDate; } } }Em seguida, você atualizará o ViewModel para receber essa mensagem e preencherá a propriedade Date do ViewModel. No Explorador de Soluções, expanda a pasta ViewModels e abra o arquivo AddNewExpenseViewModel.cs.
Localize o construtor público para a classe
AddNewExpenseViewModele adicione o seguinte código ao final do construtor. Esse código se registra para receber o SelectedDateMessage, extrai a data selecionada dele por meio da propriedade SelectedDate e o usamos para definir a propriedade Date exposta pelo ViewModel. Como essa propriedade está vinculada ao controle de TextBlock que você adicionou anteriormente, você pode ver a data selecionada pelo usuário.Messenger.Default.Register<SelectedDateMessage>(this, message => { Date = message.SelectedDate; });Quando terminar, o construtor
AddNewExpenseViewModeldeve ter esta aparência.public AddNewExpenseViewModel(IDatabaseService databaseService, IStorageService storageService) { this.databaseService = databaseService; this.storageService = storageService; Date = DateTime.Today; Messenger.Default.Register<SelectedDateMessage>(this, message => { Date = message.SelectedDate; }); }Observação
O método
SaveExpenseCommandno mesmo arquivo de código faz o trabalho de salvar as despesas para o banco de dados. Esse método usa a propriedade Date para criar o novo objeto Expense. Essa propriedade agora está sendo preenchida pelo controle CalendarView por meio da mensagemSelectedDateMessageque você acabou de criar.Pressione F5 para criar e executar o aplicativo no depurador. Escolha um dos funcionários disponíveis e clique no botão Adicionar nova despesa. Preencha todos os campos no formulário e escolha uma data através do novo controlo CalendarView. Confirme se a data selecionada é exibida como uma cadeia de caracteres abaixo do controle.
Pressione o botão Salvar. O formulário será fechado e a nova despesa será adicionada ao final da lista de despesas. A primeira coluna com a data da despesa deve ser a data selecionada no controle
CalendarView.
Próximos passos
Neste ponto do tutorial, você substituiu com êxito um controle de data e hora do WPF pelo controle de UWP
Agora você está pronto para Parte 4: Adicionar atividades de usuário do Windows e notificações.
Windows developer