Estender o aplicativo da área de trabalho com componentes UWP modernos
Algumas experiências do Windows (por exemplo, uma página de interface do usuário habilitada para toque) devem ser executadas dentro de um AppContainer. Se você quiser adicionar essas experiências, estenda o aplicativo da área de trabalho com projetos UWP e componentes do Windows Runtime.
Em muitos casos, você pode chamar APIs do Windows Runtime diretamente em seu aplicativo da área de trabalho. Portanto, antes de examinar este guia, confira Aprimorar para o Windows.
Observação
Os recursos descritos neste tópico exigem que o aplicativo seja empacotado (tenha uma identidade de pacote no runtime). Isso inclui aplicativos empacotados (confira Criar um projeto para um aplicativo da área de trabalho do WinUI 3 empacotado) e aplicativos empacotados com localização externa (confira Conceder identidade do pacote empacotando-o com localização externa). Veja também Recursos que exigem a identidade do pacote.
Primeiro, configure sua solução
Adicione um ou mais projetos UWP e componentes de runtime à sua solução.
Comece com uma solução que contenha um Projeto de Empacotamento de Aplicativo do Windows com uma referência ao seu aplicativo da área de trabalho.
Esta imagem mostra um exemplo de solução.
Caso a sua solução não contenha um projeto de empacotamento, confira Empacotar seu aplicativo da área de trabalho usando o Visual Studio.
Configurar o aplicativo da área de trabalho
Verifique se o aplicativo da área de trabalho tem referências aos arquivos de que você precisa para chamar as APIs do Windows Runtime.
Para fazer isso, confira Chamar APIs do Windows Runtime em aplicativos da área de trabalho.
Adicionar um projeto UWP
Adicionar um Aplicativo em branco (Universal do Windows) à sua solução.
Aqui, você criará uma interface XAML moderna ou usará APIs que são executadas somente dentro de um processo UWP.
No seu projeto de empacotamento, clique com botão direito no nó Aplicativos e clique em Adicionar Referência.
Depois, adicione uma referência ao projeto UWP.
A solução terá a seguinte aparência:
(Opcional) Adicionar um componente do Windows Runtime
Para realizar alguns cenários, você precisará adicionar código a um componente do Windows Runtime.
Em seguida, no projeto UWP, adicione uma referência ao componente de runtime. A solução terá a seguinte aparência:
Criar sua solução
Crie sua solução para garantir que nenhum erro seja exibido. Se você receber erros, abra Gerenciador de Configurações e verifique se os projetos se destinam à mesma plataforma.
Vamos dar uma olhada em algumas coisas que você pode fazer com seus projetos UWP e componentes de runtime.
Mostrar uma interface do usuário XAML moderna
Como parte do fluxo de seu aplicativo, você pode incorporar interfaces do usuário modernas baseadas em XAML em seu aplicativo da área de trabalho. Essas interfaces do usuário são naturalmente adaptáveis para diferentes tamanhos de tela e resoluções e dão suporte a modelos interativos modernos, como toque e tinta.
Por exemplo, com uma pequena quantidade de marcação XAML, você pode oferecer aos usuários recursos de visualização de mapa eficientes.
Esta imagem mostra um aplicativo Windows Forms que abre uma interface do usuário moderna baseada em XAML, a qual contém um controle de mapa.
Observação
Esse exemplo mostra uma interface de usuário XAML adicionando um projeto UWP à solução. Essa é a abordagem estável compatível para mostrar interfaces do usuário XAML em um aplicativo da área de trabalho. A alternativa é adicionar os controles do XAML UWP diretamente ao aplicativo da área de trabalho usando uma Ilha XAML. As ilhas XAML estão disponíveis atualmente como uma versão prévia para desenvolvedores. Embora incentivemos você a testá-los em seu próprio código de protótipo, não recomendamos que você os use no código de produção neste momento. Essas APIs e controles continuarão ser aprimorados e estabilizados em versões futuras do Windows. Para saber mais sobre as Ilhas XAML, confira Controles UWP em aplicativos da área de trabalho
O padrão de design
Para mostrar uma interface do usuário baseada em XAML, é preciso:
2️⃣ Criar uma interface do usuário XAML
3️⃣ Adicionar uma extensão de protocolo ao projeto UWP
4️⃣ Iniciar o aplicativo UWP em seu aplicativo da área de trabalho
5️⃣ No projeto UWP, mostrar a página desejada
Configurar sua solução
Para obter diretrizes gerais de como configurar a solução, confira a seção Primeiro, configure sua solução no início deste guia.
A solução terá a seguinte aparência:
Nesse exemplo, o projeto do Windows Forms é denominado Landmarks, e o projeto UWP que contém a interface do usuário XAML é denominado MapUI.
Criar uma interface do usuário XAML
Adicione uma interface do usuário XAML a seu projeto UWP. Confira o XAML do mapa básico.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="12,20,12,14">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<maps:MapControl x:Name="myMap" Grid.Column="0" Width="500" Height="500"
ZoomLevel="{Binding ElementName=zoomSlider,Path=Value, Mode=TwoWay}"
Heading="{Binding ElementName=headingSlider,Path=Value, Mode=TwoWay}"
DesiredPitch="{Binding ElementName=desiredPitchSlider,Path=Value, Mode=TwoWay}"
HorizontalAlignment="Left"
MapServiceToken="<Your Key Goes Here" />
<Grid Grid.Column="1" Margin="12">
<StackPanel>
<Slider Minimum="1" Maximum="20" Header="ZoomLevel" Name="zoomSlider" Value="17.5"/>
<Slider Minimum="0" Maximum="360" Header="Heading" Name="headingSlider" Value="0"/>
<Slider Minimum="0" Maximum="64" Header=" DesiredPitch" Name="desiredPitchSlider" Value="32"/>
</StackPanel>
</Grid>
</Grid>
Adicionar uma extensão de protocolo
No Gerenciador de Soluções, abra o arquivo package.appxmanifest do projeto de Empacotamento da sua solução e adicione esta extensão.
<Extensions>
<uap:Extension Category="windows.protocol" Executable="MapUI.exe" EntryPoint="MapUI.App">
<uap:Protocol Name="xamluidemo" />
</uap:Extension>
</Extensions>
Dê um nome ao protocolo, forneça o nome do executável produzido pelo projeto UWP e o nome da classe de ponto de entrada.
Você também pode abrir o package.appxmanifest no designer, escolher a guia Declarações e adicionar a extensão ali.
Observação
Os controles de mapa baixam dados da Internet e, se você usar um, também terá que adicionar o recurso "cliente da internet" ao seu manifesto.
Iniciar o aplicativo UWP
Primeiro, em seu aplicativo da área de trabalho, crie um Uri que inclua o nome de protocolo e os parâmetros que você deseja transmitir para o aplicativo UWP. Em seguida, chame o método LaunchUriAsync.
private void Statue_Of_Liberty_Click(object sender, EventArgs e)
{
ShowMap(40.689247, -74.044502);
}
private async void ShowMap(double lat, double lon)
{
string str = "xamluidemo://";
Uri uri = new Uri(str + "location?lat=" +
lat.ToString() + "&?lon=" + lon.ToString());
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
}
Analisar parâmetros e mostrar uma página
Na classe App do projeto UWP, substitua o manipulador de eventos OnActivated. Se o aplicativo for ativado pelo seu protocolo, analise os parâmetros e abra a página desejada.
protected override void OnActivated(Windows.ApplicationModel.Activation.IActivatedEventArgs e)
{
if (e.Kind == ActivationKind.Protocol)
{
ProtocolActivatedEventArgs protocolArgs = (ProtocolActivatedEventArgs)e;
Uri uri = protocolArgs.Uri;
if (uri.Scheme == "xamluidemo")
{
Frame rootFrame = new Frame();
Window.Current.Content = rootFrame;
rootFrame.Navigate(typeof(MainPage), uri.Query);
Window.Current.Activate();
}
}
}
No código por trás da página XAML, substitua o método OnNavigatedTo
para usar os parâmetros passados para a página. Nesse caso, usaremos a latitude e longitude passadas para essa página a fim de mostrar uma localização em um mapa.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.Parameter != null)
{
WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(e.Parameter.ToString());
double lat = Convert.ToDouble(decoder[0].Value);
double lon = Convert.ToDouble(decoder[1].Value);
BasicGeoposition pos = new BasicGeoposition();
pos.Latitude = lat;
pos.Longitude = lon;
myMap.Center = new Geopoint(pos);
myMap.Style = MapStyle.Aerial3D;
}
base.OnNavigatedTo(e);
}
Tornar seu aplicativo da área de trabalho um destino de compartilhamento
Você pode tornar seu aplicativo da área de trabalho um destino de compartilhamento para que os usuários possam compartilhar com facilidade dados como imagens de outros aplicativos que dão suporte a compartilhamento.
Por exemplo, os usuários podem escolher seu aplicativo para compartilhar fotos do Microsoft Edge, o aplicativo Fotos. Confira um aplicativo WPF de exemplo que tem esse recurso.
.
Confira o exemplo completo aqui
O padrão de design
Para tornar seu aplicativo um destino de compartilhamento, é preciso:
1️⃣ Adicionar uma extensão de destino de compartilhamento
2️⃣ Substituir o manipulador de eventos OnShareTargetActivated
3️⃣ Adicionar extensões de área de trabalho ao projeto UWP
4️⃣ Adicionar a extensão de processo de confiança total
5️⃣ Modificar o aplicativo da área de trabalho para obter o arquivo compartilhado
As etapas a seguir
Adicionar uma extensão de destino de compartilhamento
No Gerenciador de Soluções, abra o arquivo package.appxmanifest do projeto de Empacotamento da sua solução e adicione a extensão de destino de compartilhamento.
<Extensions>
<uap:Extension
Category="windows.shareTarget"
Executable="ShareTarget.exe"
EntryPoint="App">
<uap:ShareTarget>
<uap:SupportedFileTypes>
<uap:SupportsAnyFileType />
</uap:SupportedFileTypes>
<uap:DataFormat>Bitmap</uap:DataFormat>
</uap:ShareTarget>
</uap:Extension>
</Extensions>
Forneça o nome do executável produzido pelo projeto UWP e o nome da classe de ponto de entrada. Essa marcação pressupõe que o nome do executável para seu aplicativo UWP é ShareTarget.exe
.
Você também precisará especificar os tipos de arquivos que poderão ser compartilhados com seu aplicativo. Nesse exemplo, estamos tornando o aplicativo da área de trabalho WPF PhotoStoreDemo um destino de compartilhamento para imagens bitmap, portanto, especificamos Bitmap
como o tipo de arquivo com suporte.
Substituir o manipulador de eventos OnShareTargetActivated
Substitua o manipulador de eventos OnActivated na classe App do projeto UWP.
Esse manipulador de eventos é chamado quando os usuários escolhem seu aplicativo para compartilhar arquivos.
protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
shareWithDesktopApplication(args.ShareOperation);
}
private async void shareWithDesktopApplication(ShareOperation shareOperation)
{
if (shareOperation.Data.Contains(StandardDataFormats.StorageItems))
{
var items = await shareOperation.Data.GetStorageItemsAsync();
StorageFile file = items[0] as StorageFile;
IRandomAccessStreamWithContentType stream = await file.OpenReadAsync();
await file.CopyAsync(ApplicationData.Current.LocalFolder);
shareOperation.ReportCompleted();
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
}
}
Nesse código, salvamos a imagem que está sendo compartilhada pelo usuário em uma pasta de armazenamento local de aplicativos. Em seguida, modificaremos o aplicativo da área de trabalho para extrair imagens da mesma pasta. O aplicativo da área de trabalho pode fazer isso porque ele está incluído no mesmo pacote que o aplicativo UWP.
Adicionar extensões de área de trabalho ao projeto UWP
Adicione a extensão Extensões da área de trabalho do Windows para UWP ao projeto de aplicativo UWP. Você verá mais de uma versão da extensão (por exemplo, 10.0.18362.0 e 10.0.19041.0). Para obter informações sobre como escolher uma versão, confira SDKs de extensão e como referenciá-los.
Adicionar a extensão de processo de confiança total
No Explorador de soluções, abra o arquivo package.appxmanifest no projeto de Empacotamento na sua solução e adicione a extensão de processo de confiança total ao lado da extensão de destino de compartilhamento que você adicionou a esse arquivo anteriormente.
<Extensions>
...
<desktop:Extension Category="windows.fullTrustProcess" Executable="PhotoStoreDemo\PhotoStoreDemo.exe" />
...
</Extensions>
Essa extensão permitirá que o aplicativo UWP inicie o aplicativo da área de trabalho com o qual você deseja compartilhar um arquivo. No exemplo, fazemos referência ao executável do aplicativo da área de trabalho WPF PhotoStoreDemo.
Modificar o aplicativo da área de trabalho para obter o arquivo compartilhado
Modifique o aplicativo da área de trabalho para encontrar e processar o arquivo compartilhado. Neste exemplo, o aplicativo UWP armazenou o arquivo compartilhado na pasta de dados do aplicativo local. Portanto, modificaremos o aplicativo da área de trabalho WPF PhotoStoreDemo para extrair fotos dessa pasta.
Photos.Path = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
Para instâncias do aplicativo da área de trabalho já abertas pelo usuário, também podemos manipular o evento FileSystemWatcher e passar o caminho para o local do arquivo. Dessa forma, qualquer instância aberta do aplicativo da área de trabalho mostrará a foto compartilhada.
...
FileSystemWatcher watcher = new FileSystemWatcher(Photos.Path);
...
private void Watcher_Created(object sender, FileSystemEventArgs e)
{
// new file got created, adding it to the list
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
{
if (File.Exists(e.FullPath))
{
ImageFile item = new ImageFile(e.FullPath);
Photos.Insert(0, item);
PhotoListBox.SelectedIndex = 0;
CurrentPhoto.Source = (BitmapSource)item.Image;
}
}));
}
Criar uma tarefa em segundo plano
Adicione uma tarefa em segundo plano para executar o código, mesmo quando o aplicativo estiver suspenso. É ótimo deixar em segundo plano tarefas pequenas que não exigem a interação do usuário. Por exemplo, sua tarefa pode baixar emails, mostrar uma notificação do sistema sobre uma mensagem de chat recebida ou reagir a uma alteração em uma condição do sistema.
Este é um exemplo de aplicativo WPF que registra uma tarefa em segundo plano.
A tarefa faz uma solicitação http e mede o tempo que leva para a solicitação retornar uma resposta. As tarefas provavelmente serão muito mais interessantes, mas esse exemplo é ótimo para aprender a mecânica básica de uma tarefa em segundo plano.
Confira o exemplo completo aqui.
O padrão de design
Para criar um serviço em segundo plano, é preciso:
1️⃣ Implementar a tarefa em segundo plano
2️⃣ Configurar a tarefa em segundo plano
3️⃣ Registrar a tarefa em segundo plano
Implementar a tarefa em segundo plano
Implemente a tarefa em segundo plano adicionando código a um projeto de componente do Windows Runtime.
public sealed class SiteVerifier : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += TaskInstance_Canceled;
BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
var msg = await MeasureRequestTime();
ShowToast(msg);
deferral.Complete();
}
private async Task<string> MeasureRequestTime()
{
string msg;
try
{
var url = ApplicationData.Current.LocalSettings.Values["UrlToVerify"] as string;
var http = new HttpClient();
Stopwatch clock = Stopwatch.StartNew();
var response = await http.GetAsync(new Uri(url));
response.EnsureSuccessStatusCode();
var elapsed = clock.ElapsedMilliseconds;
clock.Stop();
msg = $"{url} took {elapsed.ToString()} ms";
}
catch (Exception ex)
{
msg = ex.Message;
}
return msg;
}
Configurar a tarefa em segundo plano
No designer de manifesto, abra o arquivo package.appxmanifest do projeto de Empacotamento em sua solução.
Na guia Declarações, adicione uma declaração Tarefas em segundo plano.
Em seguida, escolha as propriedades desejadas. Nosso exemplo usa a propriedade Timer.
Forneça o nome totalmente qualificado da classe no seu componente do Windows Runtime que implementa a tarefa em segundo plano.
Registrar a tarefa em segundo plano
Adicione código ao seu projeto de aplicativo da área de trabalho que registra a tarefa em segundo plano.
public void RegisterBackgroundTask(String triggerName)
{
var current = BackgroundTaskRegistration.AllTasks
.Where(b => b.Value.Name == triggerName).FirstOrDefault().Value;
if (current is null)
{
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = triggerName;
builder.SetTrigger(new MaintenanceTrigger(15, false));
builder.TaskEntryPoint = "HttpPing.SiteVerifier";
builder.Register();
System.Diagnostics.Debug.WriteLine("BGTask registered:" + triggerName);
}
else
{
System.Diagnostics.Debug.WriteLine("Task already:" + triggerName);
}
}
Encontrar respostas para suas dúvidas
Tem dúvidas? Pergunte-nos no Stack Overflow. Nossa equipe monitora estas marcas. Você também pode entrar em contato conosco aqui.
Windows developer