Compartilhar via


Portabilidade de projetos do Windows Phone Silverlight para projetos UWP

O tópico anterior foi Mapeamentos de namespace e classe.

Você inicia o processo de portabilidade criando um novo projeto do Windows 10 no Visual Studio e copiando seus arquivos para ele.

Crie o projeto e copie os arquivos para ele

  1. Inicie o Microsoft Visual Studio 2015 e crie um novo projeto de Aplicativo em Branco (Windows Universal). Para obter mais informações, consulte Iniciar seu aplicativo do Tempo de Execução do Windows 8.x usando modelos (C#, C++, Visual Basic). Seu novo projeto cria um pacote de aplicativos (um arquivo appx) que será executado em todas as famílias de dispositivos.
  2. Em seu projeto de aplicativo do Windows Phone Silverlight, identifique todos os arquivos de código-fonte e arquivos de ativos visuais que você deseja reutilizar. Usando o Explorador de Arquivos, copie modelos de dados, modelos de exibição, ativos visuais, dicionários de recursos, estrutura de pastas e qualquer outra coisa que você deseja reutilizar para seu novo projeto. Copie ou crie subpastas no disco, conforme necessário.
  3. Copie exibições (por exemplo, MainPage.xaml e MainPage.xaml.cs) para o novo nó do projeto também. Novamente, crie novas subpastas conforme necessário e remova as visualizações existentes do projeto. Mas, antes de substituir ou remover um modo de exibição gerado pelo Visual Studio, mantenha uma cópia, pois pode ser útil consultá-lo mais tarde. A primeira fase da portabilidade de um aplicativo do Windows Phone Silverlight se concentra em fazer com que ele tenha uma boa aparência e funcione bem em uma família de dispositivos. Mais tarde, você voltará sua atenção para garantir que as exibições se adaptem bem a todos os fatores forma e, opcionalmente, para adicionar qualquer código adaptável para obter o máximo de uma família de dispositivos específica.
  4. No Gerenciador de Soluções, verifique se Mostrar Todos os Arquivos está ativado. Selecione os arquivos que você copiou, clique com o botão direito do mouse neles e clique em Incluir no projeto. Isso incluirá automaticamente as pastas que as contêm. Você pode desativar Mostrar todos os arquivos, se desejar. Um fluxo de trabalho alternativo, se preferir, é usar o comando Adicionar Item Existente, tendo criado todas as subpastas necessárias no Gerenciador de Soluções do Visual Studio. Verifique novamente se os ativos visuais têm a Ação de Build definida como Conteúdo e a Cópia para o diretório de saída definida como Não copiar.
  5. As diferenças nos nomes de namespace e classe gerarão muitos erros de compilação neste estágio. Por exemplo, se você abrir os modos de exibição gerados pelo Visual Studio, verá que eles são do tipo Page e não PhoneApplicationPage. Há muitas diferenças de código imperativo e marcação XAML que os tópicos a seguir neste guia de portabilidade abordam em detalhes. Mas você fará um progresso rápido apenas seguindo estas etapas gerais: altere "clr-namespace" para "using" em suas declarações de prefixo de namespace na marcação XAML; use o tópico Mapeamentos de namespace e classe e o comando Localizar e Substituir do Visual Studio para fazer alterações em massa no código-fonte (por exemplo, substitua "System.Windows" por "Windows.UI.Xaml"); e no editor de código imperativo no Visual Studio, use os comandos Resolver e Organizar Usos no menu de contexto para alterações mais direcionadas.

SDKs de extensão

A maioria das APIs da Plataforma Universal do Windows (UWP) que seu aplicativo portado chamará são implementadas no conjunto de APIs conhecido como família de dispositivos universal. No entanto, alguns são implementados em SDKs de extensão e o Visual Studio reconhece apenas APIs implementadas pela família de dispositivos de destino do aplicativo ou por qualquer SDK de extensão que você tenha referenciado.

Se você receber erros de compilação sobre namespaces, tipos ou membros que não puderam ser encontrados, é provável que essa seja a causa. Abra o tópico da API na documentação de referência da API e navegue até a seção Requisitos: que informará qual é a família de dispositivos de implementação. Se essa não for sua família de dispositivos de destino, para disponibilizar a API para seu projeto, você precisará de uma referência ao SDK de extensão para essa família de dispositivos.

Clique em Projetar>Adicionar Referência de Extensões> Universais>do Windows e selecione o SDK de extensão apropriado. Por exemplo, se as APIs que você deseja chamar estiverem disponíveis apenas na família de dispositivos móveis e tiverem sido introduzidas na versão 10.0.x.y, selecione Extensões do Windows Mobile para a UWP.

Isso adicionará a seguinte referência ao seu arquivo de projeto:

<ItemGroup>
    <SDKReference Include="WindowsMobile, Version=10.0.x.y">
        <Name>Windows Mobile Extensions for the UWP</Name>
    </SDKReference>
</ItemGroup>

O nome e o número da versão correspondem às pastas no local instalado do SDK. Por exemplo, as informações acima correspondem a este nome de pasta:

\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsMobile\10.0.x.y

A menos que seu aplicativo tenha como destino a família de dispositivos que implementa a API, você precisará usar a classe ApiInformation para testar a presença da API antes de chamá-la (isso é chamado de código adaptável). Essa condição será avaliada sempre que seu aplicativo for executado, mas só será avaliada como verdadeira em dispositivos em que a API está presente e, portanto, disponível para chamada. Use SDKs de extensão e código adaptável somente depois de verificar se existe uma API universal. Alguns exemplos são dados na seção abaixo.

Além disso, consulte Manifesto do pacote do aplicativo.

Maximizando a marcação e a reutilização de código

Você descobrirá que refatorar um pouco e/ou adicionar código adaptável (que é explicado abaixo) permitirá maximizar a marcação e o código que funciona em todas as famílias de dispositivos. Aqui estão mais detalhes.

  • Os arquivos comuns a todas as famílias de dispositivos não precisam de consideração especial. Esses arquivos serão usados pelo aplicativo em todas as famílias de dispositivos em que ele é executado. Isso inclui arquivos de marcação XAML, arquivos de código-fonte imperativos e arquivos de ativos.
  • É possível que seu aplicativo detecte a família de dispositivos em que está sendo executado e navegue até uma exibição que foi projetada especificamente para essa família de dispositivos. Para obter mais detalhes, consulte Detectando a plataforma em que seu aplicativo está sendo executado.
  • Uma técnica semelhante que pode ser útil se não houver alternativa é dar a um arquivo de marcação ou arquivo ResourceDictionary (ou a pasta que contém o arquivo) um nome especial para que ele seja carregado automaticamente em tempo de execução somente quando seu aplicativo for executado em uma família de dispositivos específica. Essa técnica é ilustrada no estudo de caso Bookstore1.
  • Para usar recursos que não estão disponíveis em todas as famílias de dispositivos (por exemplo, impressoras, scanners ou o botão da câmera), você pode escrever código adaptável. Consulte o terceiro exemplo em Compilação condicional e código adaptável neste tópico.
  • Se você quiser dar suporte ao Windows Phone Silverlight e ao Windows 10, poderá compartilhar arquivos de código-fonte entre projetos. Veja como: no Visual Studio, clique com o botão direito do mouse no projeto no Gerenciador de Soluções, selecione Adicionar Item Existente, selecione os arquivos a serem compartilhados e clique em Adicionar como Link. Armazene seus arquivos de código-fonte em uma pasta comum no sistema de arquivos onde os projetos vinculados a eles possam vê-los e não se esqueça de adicioná-los ao controle do código-fonte. Se você puder fatorar seu código-fonte imperativo para que a maioria, se não todos, de um arquivo funcione em ambas as plataformas, não precisará ter duas cópias dele. Você pode encapsular qualquer lógica específica da plataforma no arquivo dentro de diretivas de compilação condicional sempre que possível ou condições de tempo de execução quando necessário. Consulte a próxima seção abaixo e as diretivas de pré-processador C#.
  • Para reutilização no nível binário, em vez do nível do código-fonte, há Bibliotecas de Classes Portáteis, que dão suporte ao subconjunto de APIs do .NET disponíveis no Windows Phone Silverlight, bem como ao subconjunto de aplicativos do Windows 10 (.NET Core). Os assemblies da Biblioteca de Classes Portátil são compatíveis com binários com essas plataformas .NET e muito mais. Use o Visual Studio para criar um projeto direcionado a uma Biblioteca de Classes Portátil. Consulte Desenvolvimento multiplataforma com a Biblioteca de Classes Portátil.

Compilação condicional e código adaptável

Se você quiser dar suporte ao Windows Phone Silverlight e ao Windows 10 em um único arquivo de código, poderá fazer isso. Se você examinar seu projeto do Windows 10 nas páginas de propriedades do projeto, verá que o projeto define WINDOWS_UAP como um símbolo de compilação condicional. Em geral, você pode usar a lógica a seguir para executar a compilação condicional.

#if WINDOWS_UAP
    // Code that you want to compile into the Windows 10/11 app.
#else
    // Code that you want to compile into the Windows Phone Silverlight app.
#endif // WINDOWS_UAP

Se você tiver um código que está compartilhando entre um aplicativo do Windows Phone Silverlight e um aplicativo do Tempo de Execução do Windows 8.x, talvez já tenha o código-fonte com uma lógica como esta:

#if NETFX_CORE
    // Code that you want to compile into the Windows Runtime 8.x app.
#else
    // Code that you want to compile into the Windows Phone Silverlight app.
#endif // NETFX_CORE

Nesse caso, e se agora você deseja oferecer suporte ao Windows 10 adicionalmente, também pode fazer isso.

#if WINDOWS_UAP
    // Code that you want to compile into the Windows 10/11 app.
#else
#if NETFX_CORE
    // Code that you want to compile into the Windows Runtime 8.x app.
#else
    // Code that you want to compile into the Windows Phone Silverlight app.
#endif // NETFX_CORE
#endif // WINDOWS_UAP

Você pode ter usado a compilação condicional para limitar o manuseio do botão Voltar do hardware ao Windows Phone. No Windows 10, o evento do botão Voltar é um conceito universal. Os botões Voltar implementados no hardware ou no software gerarão o evento BackRequested , portanto, é esse o único a ser manipulado.

       Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested +=
            this.ViewModelLocator_BackRequested;

...

    private void ViewModelLocator_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
    {
        // Handle the event.
    }

Você pode ter usado a compilação condicional para limitar o manuseio do botão da câmera de hardware ao Windows Phone. No Windows 10, o botão da câmera de hardware é um conceito específico da família de dispositivos móveis. Como um pacote de aplicativo estará em execução em todos os dispositivos, alteramos nossa condição de tempo de compilação para uma condição de tempo de execução usando o que é conhecido como código adaptável. Para fazer isso, usamos a classe ApiInformation para consultar em tempo de execução a presença da classe HardwareButtons. HardwareButtons é definido no SDK da extensão móvel, portanto, precisaremos adicionar uma referência a esse SDK ao nosso projeto para que esse código seja compilado. Observe, porém, que o manipulador só será executado em um dispositivo que implemente os tipos definidos no SDK da extensão móvel, e essa é a família de dispositivos móveis. Portanto, o código a seguir tem o cuidado de usar apenas os recursos que estão presentes, embora o alcance de uma maneira diferente da compilação condicional.

       // Note: Cache the value instead of querying it more than once.
        bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsTypePresent
            ("Windows.Phone.UI.Input.HardwareButtons");

        if (isHardwareButtonsAPIPresent)
        {
            Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
                this.HardwareButtons_CameraPressed;
        }

    ...

    private void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
    {
        // Handle the event.
    }

Além disso, consulte Detectando a plataforma em que seu aplicativo está sendo executado.

O manifesto do pacote do aplicativo

As configurações em seu projeto (incluindo quaisquer referências de SDKs de extensão) determinam a área de superfície da API que seu aplicativo pode chamar. No entanto, o manifesto do pacote do aplicativo é o que determina o conjunto real de dispositivos nos quais seus clientes podem instalar seu aplicativo na Loja. Para obter mais informações, consulte Exemplos em TargetDeviceFamily.

Vale a pena saber como editar o manifesto do pacote do aplicativo, pois os tópicos a seguir falam sobre como usá-lo para várias declarações, recursos e outras configurações que alguns recursos precisam. Você pode usar o editor de manifesto do pacote do aplicativo Visual Studio para editá-lo. Se o Gerenciador de Soluções não for mostrado, escolha-o no menu Exibir . Clique duas vezes em Package.appxmanifest. Isso abre a janela do editor de manifesto. Selecione a guia apropriada para fazer alterações e salve-as. Talvez você queira garantir que o elemento pm:PhoneIdentity no manifesto do aplicativo portado corresponda ao que está no manifesto do aplicativo que você está portando (para obter detalhes completos, consulte o tópico pm:PhoneIdentity ).

Consulte Referência de esquema de manifesto do pacote para Windows 10.

O próximo tópico é Solução de problemas.