Uma migração do SDK do Aplicativo Windows do aplicativo de exemplo PhotoLab da UWP (C#)

Este tópico é um estudo de caso de como usar o aplicativo UWP de exemplo PhotoLab em C# e migrá-lo para o SDK do Aplicativo Windows.

Comece clonando o repositório do aplicativo de amostra UWP e abrindo a solução no Visual Studio.

Importante

Para considerações e estratégias para abordar o processo de migração e como configurar seu ambiente de desenvolvimento para migração, consulte Estratégia geral de migração. É particularmente importante consultar O que é suportado ao portar da UWP para a WinUI 3, para que você possa garantir que todos os recursos necessários para o aplicativo tenham suporte antes de tentar a migração.

Instalar ferramentas para o SDK do Aplicativo Windows

Para configurar o ambiente de desenvolvimento, confira Instalar ferramentas para o SDK do Aplicativo Windows.

Importante

Você encontrará tópicos de notas de versão com o tópico Canais de versão do SDK do Aplicativo Windows. Há notas de versão para cada canal. Verifique as limitações e os problemas conhecidos nas notas de versão, pois eles podem afetar os resultados de acompanhar este estudo de caso e/ou executar o aplicativo migrado.

Crie um novo projeto

No Visual Studio, crie um projeto em C# com base no modelo de projeto Aplicativo em Branco, Empacotado (WinUI 3 na Área de Trabalho). Chame o projeto de PhotoLabWinUI, desmarque Colocar solução e projeto no mesmo diretório. Você pode ter como alvo a versão mais recente (não a versão prévia) do sistema operacional cliente.

Observação

Faremos referência à versão UWP do projeto de amostra (aquela que você clonou de seu repositório) como a solução/projeto de origem. Faremos referência à versão do SDK do Aplicativo Windows como a solução/projeto de destino.

A ordem em que migraremos o código

MainPage é uma peça importante e proeminente do aplicativo. Porém, se começássemos migrando isso, logo perceberíamos que MainPage tem uma dependência pelo modo de exibição DetailPage e, em seguida, que DetailPage tem uma dependência pelo modelo ImageFileInfo. Portanto, para este passo a passo, adotaremos essa abordagem.

  • Começaremos copiando os arquivos de ativos.
  • Em seguida, migraremos o modelo ImageFileInfo.
  • Em seguida, migraremos a classe App (já que isso alterações das quais DetailPage, MainPage e LoadedImageBrush dependerão).
  • Em seguida, migraremos a classe LoadedImageBrush.
  • Em seguida, começaremos a migrar exibições, começando com DetailPage.
  • E terminaremos migrando a visualização MainPage.

Copiar arquivos de ativo

  1. Em seu projeto de destino no Visual Studio, no Gerenciador de Soluções, clique com o botão direito do mouse na pasta Ativos e adicione uma nova pasta chamada Samples.

  2. No clone do projeto de origem, no Explorador de Arquivos, localize a pasta Windows-appsample-photo-lab>PhotoLab>Assets. Você encontrará sete arquivos de ativos nessa pasta, juntamente com uma subpasta chamada Samples, que contém imagens de amostra. Selecione esses sete arquivos de ativos e a subpasta Samples e copie-os para a área de transferência.

  3. Também no Explorador de Arquivos, agora localize a pasta correspondente no projeto de destino que você criou. O caminho para essa pasta é PhotoLabWinUI>PhotoLabWinUI>Assets. Cole nessa pasta os arquivos de ativos e a subpasta que você acabou de copiar e aceite o prompt para substituir todos os arquivos já existentes no destino.

  4. No projeto de destino no Visual Studio, no Gerenciador de Soluções, com a pasta Assets expandida, você verá na pasta Samples o conteúdo da subpasta Samples (que acabou de colar). É possível passar o ponteiro do mouse sobre os arquivos de ativos. Uma visualização em miniatura será exibida para cada um, confirmando que você os substituiu/adicionou corretamente.

Migrar o modelo ImageFileInfo

ImageFileInfo é um modelo (no sentido de modelos, modos de exibição e modelos de exibição) que representa um arquivo de imagem, como uma foto.

Copiar arquivos de código-fonte de ImageFileInfo

  1. No clone do projeto de origem, no Explorador de Arquivos, localize a pasta Windows-appsample-photo-lab>PhotoLab. Nessa pasta, você encontrará o arquivo de código-fonte ImageFileInfo.cs, que contém a implementação de ImageFileInfo. Selecione-o e copie-o para a área de transferência.

  2. No Visual Studio, clique com o botão direito do mouse no nó do projeto de destino e clique em Abrir Pasta no Explorador de Arquivos. Isso abre a pasta do projeto no Explorador de Arquivos. Cole nessa pasta o arquivo que acabou de copiar.

Migrar o código-fonte de ImageFileInfo

  1. Faça as seguintes localizações/substituições (correspondência entre maiúsculas e minúsculas e palavra inteira) no arquivo ImageFileInfo.cs que você acabou de colar.
  • namespace PhotoLab =>namespace PhotoLabWinUI
  • Windows.UI.Xaml =>Microsoft.UI.Xaml

Windows.UI.Xaml é o namespace para UWP XAML; Microsoft.UI.Xaml é o namespace para WinUI XAML.

Observação

O tópico Mapeando APIs UWP para o SDK do Aplicativo Windows fornece um mapeamento de APIs UWP para seus equivalentes no SDK do Aplicativo Windows. A alteração que fizemos acima é um exemplo de alteração em nome de namespace necessária durante o processo de migração.

  1. Agora, confirme que você pode criar a solução de destino (mas não a execute ainda).

Migrar a classe App

  1. No projeto de origem, no elemento <Application.Resources> em App.xaml, localize as quatro linhas a seguir. Copie-as e cole-as no projeto de destino.
<SolidColorBrush x:Key="RatingControlSelectedForeground" Color="White"/>
<!--  Window width adaptive breakpoints.  -->
<x:Double x:Key="MinWindowBreakpoint">0</x:Double>
<x:Double x:Key="MediumWindowBreakpoint">641</x:Double>
<x:Double x:Key="LargeWindowBreakpoint">1008</x:Double>

Observação

Como o projeto de destino usará navegação diferente (e mais simples) do projeto de origem, não há necessidade de copiar código adicional do App.xaml.cs desse projeto de origem.

  1. No projeto de destino, App armazena o objeto de janela principal no seu campo privado m_window. Mais tarde, no processo de migração (quando migrarmos o uso de Window.Current pelo projeto de origem), será conveniente se esse campo privado for uma propriedade estática pública. Portanto, substitua o campo m_window por uma propriedade Window e altere as referências a m_window, conforme mostrado abaixo.
// App.xaml.cs
public partial class App : Application
{
    ...
    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        Window = new MainWindow();
        Window.Activate();
    }

    public static MainWindow Window { get; private set; }
}
  1. Mais tarde, no processo de migração (quando migramos o código que exibe um FileSavePicker), será conveniente se App expuser o identificador da janela principal (HWND). Portanto, adicione uma propriedade WindowHandle e inicialize-a no método OnLaunched , como mostrado abaixo.
// App.xaml.cs
public partial class App : Application
{
    ...
    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        Window = new MainWindow();
        Window.Activate();
        WindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(Window);
    }

    public static IntPtr WindowHandle { get; private set; }
}

Migrar o modelo LoadedImageBrush

LoadedImageBrush é uma especialização de XamlCompositionBrushBase. O aplicativo de amostra PhotoLab usa a classe LoadedImageBrush para aplicar efeitos a fotos.

Referenciar o pacote NuGet Win2D

Para dar suporte ao código em LoadedImageBrush, o projeto de origem tem uma dependência por Win2D. Por isso, também precisaremos de uma dependência por Win2D em nosso projeto de destino.

Na solução de destino no Visual Studio, clique em Ferramentas>Gerenciador de Pacotes NuGet>Gerenciar Pacotes NuGet para Solução...>Procurar e digite ou cole Microsoft.Graphics.Win2D. Selecione o item correto nos resultados da pesquisa, verifique o projeto PhotoLabWinUI e clique em Instalar para instalar o pacote nesse projeto.

Copiar arquivos de código-fonte de LoadedImageBrush

Copie LoadedImageBrush.cs do projeto de origem para o projeto de destino da mesma maneira que você copiou ImageFileInfo.cs.

Migrar o código-fonte de LoadedImageBrush

  1. Faça as seguintes localizações/substituições (correspondência entre maiúsculas e minúsculas e palavra inteira) no arquivo LoadedImageBrush.cs que você acabou de colar.
  1. Confirme que você pode criar a solução de destino (mas não a execute ainda).

Migrar o modo de exibição de DetailPage

DetailPage é a classe que representa a página do editor de fotos, na qual efeitos Win2D são alternados, definidos e encadeados. Você acessa a página do editor de fotos selecionando uma miniatura de foto em MainPage. DetailPage é um modelo (no sentido de modelos, modos de exibição e modelos de visualização).

Copiar arquivos de código-fonte de DetailPage

Copie DetailPage.xaml e DetailPage.xaml.cs do projeto de origem para o projeto de destino da mesma maneira que você copiou arquivos nas etapas anteriores.

Migrar o código-fonte de DetailPage

  1. Faça as seguintes localizações/substituições (correspondência entre maiúsculas e minúsculas e palavra inteira) no arquivo DetailPage.xaml que você acabou de colar.
  • PhotoLab =>PhotoLabWinUI
  1. Faça as seguintes localizações/substituições (correspondência entre maiúsculas e minúsculas e palavra inteira) no arquivo DetailPage.xaml.cs que você acabou de colar.
  • namespace PhotoLab =>namespace PhotoLabWinUI
  • Windows.UI.Colors =>Microsoft.UI.Colors
  • Windows.UI.Xaml =>Microsoft.UI.Xaml
  1. Para a próxima etapa, faremos a alteração explicada em ContentDialog e Popup. Então, ainda em DetailPage.xaml.cs, no método ShowSaveDialog, logo antes da linha ContentDialogResult result = await saveDialog.ShowAsync();, adicione esse código.
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
    saveDialog.XamlRoot = this.Content.XamlRoot;
}
  1. Ainda em DetailPage.xaml.cs, no método OnNavigatedTo, exclua as duas linhas de código a seguir. Apenas essas duas linhas. Mais tarde, neste estudo de caso, reintroduziremos a funcionalidade do botão Voltar, que acabamos de remover.
...
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
    AppViewBackButtonVisibility.Visible;
...
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = 
    AppViewBackButtonVisibility.Collapsed;
...
  1. Para essa etapa, faremos a alteração explicada em MessageDialog e Pickers. Ainda em DetailPage.xaml.cs, no método ExportImage, logo antes da linha var outputFile = await fileSavePicker.PickSaveFileAsync();, adicione essa linha de código.
WinRT.Interop.InitializeWithWindow.Initialize(fileSavePicker, App.WindowHandle);

MainPage tem dependências por DetailPage, e é por isso que migramos DetailPage primeiro. Porém, DetailPage também tem dependências por MainPage, então ainda não poderemos compilar.

Migrar o modo de exibição MainPage

A página principal do aplicativo representa a exibição que você vê primeiro quando executa o aplicativo. É a página que carrega as fotos da pasta Samples incorporada ao aplicativo de amostra e exibe uma exibição de miniatura lado a lado.

Copiar arquivos de código-fonte de MainPage

Copie MainPage.xaml e MainPage.xaml.cs do projeto de origem para o projeto de destino da mesma maneira que você copiou arquivos nas etapas anteriores.

Migrar o código-fonte de MainPage

  1. Faça as seguintes localizações/substituições (correspondência entre maiúsculas e minúsculas e palavra inteira) no arquivo MainPage.xaml que você acabou de colar.
  • PhotoLab =>PhotoLabWinUI
  1. Ainda em MainPage.xaml, encontre a marcação animations:ReorderGridAnimation.Duration="400" e exclua-a.

  2. Faça as seguintes localizações/substituições (correspondência entre maiúsculas e minúsculas e palavra inteira) no arquivo MainPage.xaml.cs que você acabou de colar.

  • namespace PhotoLab =>namespace PhotoLabWinUI
  • Windows.UI.Xaml =>Microsoft.UI.Xaml
  1. Para essa etapa, faremos a alteração explicada em ContentDialog e Popup. Então, ainda em MainPage.xaml.cs, no método GetItemsAsync, logo antes da linha ContentDialogResult resultNotUsed = await unsupportedFilesDialog.ShowAsync();, adicione esse código.
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
    unsupportedFilesDialog.XamlRoot = this.Content.XamlRoot;
}
  1. Ainda em MainPage.xaml.cs, no método OnNavigatedTo, exclua a seguinte linha de código.
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
    AppViewBackButtonVisibility.Collapsed;

Mais tarde, neste estudo de caso, reintroduziremos a funcionalidade do botão Voltar, que acabamos de remover.

  1. Confirme que você pode criar a solução de destino (mas não a execute ainda).

O aplicativo de amostra PhotoLab usa lógica de navegação para navegar inicialmente até MainPage (e depois entre MainPage e DetailPage). Para saber mais sobre aplicativos do SDK do Aplicativo Windows que precisam de navegação (e os que não precisam), consulte Preciso implementar a navegação de página?.

Portanto, as alterações que faremos a seguir dão suporte para essa navegação.

  1. Em MainWindow.xaml, exclua o elemento <StackPanel> e substitua-o por apenas um elemento <Frame>. O resultado será semelhante a este:
<Window ...>
    <Frame x:Name="rootFrame"/>
</Window>
  1. Em MainWindow.xaml.cs, exclua o método myButton_Click.

  2. Ainda em MainWindow.xaml.cs, adicione a seguinte linha de código ao construtor.

public sealed partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
        rootFrame.Navigate(typeof(MainPage));
    }
}
  1. Confirme que você pode criar a solução de destino (mas não a execute ainda).

Restaurando a funcionalidade do botão Voltar

  1. Em DetailPage.xaml, o elemento raiz é RelativePanel. Adicione a seguinte marcação dentro desse RelativePanel, imediatamente após o elemento StackPanel.
<AppBarButton x:Name="BackButton" Click="BackButton_Click" Margin="0,0,12,0">
    <SymbolIcon Symbol="Back"/>
</AppBarButton>
  1. Em DetailPage.xaml.cs, adicione as duas linhas de código a seguir ao método OnNavigatedTo, no local indicado.
if (this.Frame.CanGoBack)
{
    BackButton.Visibility = Microsoft.UI.Xaml.Visibility.Visible;
}
else
{
    BackButton.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed;
}
  1. Ainda em DetailPage.xaml.cs, adicione o seguinte manipulador de eventos.
private void BackButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
    Frame.GoBack();
}

Testar o aplicativo migrado

Agora, crie o projeto e execute o aplicativo para testá-lo. Selecione uma imagem, defina um nível de zoom, escolha efeitos e configure-os.