Estudo de caso do Tempo de Execução do Windows 8.x para UWP: Bookstore2
Este estudo de caso, que se baseia nas informações fornecidas em Bookstore1, começa com um aplicativo Universal 8.1 que exibe dados agrupados em um controle SemanticZoom. No modelo de exibição, cada instância da classe Author representa o grupo de livros escritos por esse autor e, no SemanticZoom, podemos exibir a lista de livros agrupados por autor ou diminuir o zoom para ver uma lista de atalhos de autores. A lista de atalhos proporciona uma navegação mais rápida do que rolar pela lista de livros. Percorremos as etapas de portabilidade do aplicativo para um aplicativo UWP (Plataforma Universal do Windows) do Windows 10.
Observação Ao abrir Bookstore2Universal_10 no Visual Studio, se você vir a mensagem "Atualização do Visual Studio necessária", siga as etapas em TargetPlatformVersion.
Downloads
Baixe o aplicativo Bookstore2_81 Universal 8.1.
Baixe o aplicativo Bookstore2Universal_10 Windows 10.
O aplicativo Universal 8.1
Veja como é o Bookstore2_81, o aplicativo que vamos portar. É um SemanticZoom de rolagem horizontal (rolagem vertical no Windows Phone) que mostra livros agrupados por autor. Você pode diminuir o zoom para a lista de atalhos e, a partir daí, navegar de volta para qualquer grupo. Há duas partes principais desse aplicativo: o modelo de exibição que fornece a fonte de dados agrupada e a interface do usuário que se associa a esse modelo de exibição. Como veremos, essas duas peças são facilmente portadas da tecnologia WinRT 8.1 para o Windows 10.
Bookstore2_81 no Windows, visualização ampliada
Bookstore2_81 no Windows, visualização reduzida
Bookstore2_81 no Windows Phone, modo de exibição ampliado
Bookstore2_81 no Windows Phone, modo de exibição reduzido
Portabilidade para um projeto do Windows 10
A solução Bookstore2_81 é um projeto de aplicativo universal 8.1. O projeto Bookstore2_81.Windows cria o pacote do aplicativo para Windows 8.1 e o projeto Bookstore2_81.WindowsPhone cria o pacote do aplicativo para Windows Phone 8.1. Bookstore2_81.Shared é o projeto que contém código-fonte, arquivos de marcação e outros ativos e recursos, que são usados por ambos os outros dois projetos.
Assim como no estudo de caso anterior, a opção que tomaremos (das descritas em Se você tiver um aplicativo Universal 8.1) é portar o conteúdo do projeto Compartilhado para um Windows 10 direcionado à família de dispositivos Universal.
Comece criando um novo projeto de Aplicativo em Branco (Windows Universal). Nomeie-o Bookstore2Universal_10. Estes são os arquivos a serem copiados do Bookstore2_81 para o Bookstore2Universal_10.
Do projeto Compartilhado
- Copie a pasta que contém os arquivos PNG da imagem da capa do livro (a pasta é \Assets\CoverImages). Depois de copiar a pasta, no Gerenciador de Soluções, verifique se Mostrar Todos os Arquivos está ativado. Clique com o botão direito do mouse na pasta que você copiou e clique em Incluir no projeto. Esse comando é o que queremos dizer com "incluir" arquivos ou pastas em um projeto. Cada vez que você copiar um arquivo ou pasta, a cada cópia, clique em Atualizar no Gerenciador de Soluções e inclua o arquivo ou pasta no projeto. Não há necessidade de fazer isso para arquivos que você está substituindo no destino.
- Copie a pasta que contém o arquivo de origem do modelo de exibição (a pasta é \ViewModel).
- Copie MainPage.xaml e substitua o arquivo no destino.
Do projeto do Windows
- Copie BookstoreStyles.xaml. Usaremos este como um bom ponto de partida porque todas as chaves de recurso neste arquivo serão resolvidas em um aplicativo do Windows 10; alguns deles no arquivo equivalente do WindowsPhone não.
- Copie SeZoUC.xaml e SeZoUC.xaml.cs. Começaremos com a versão Windows dessa visualização, que é apropriada para janelas largas e, posteriormente, faremos com que ela se adapte a janelas menores e, consequentemente, a dispositivos menores.
Edite o código-fonte e os arquivos de marcação que você acabou de copiar e altere todas as referências ao namespace Bookstore2_81 para Bookstore2Universal_10. Uma maneira rápida de fazer isso é usar o recurso Substituir em arquivos . Nenhuma alteração de código é necessária no modelo de exibição, nem em qualquer outro código imperativo. Mas, apenas para facilitar a visualização de qual versão do aplicativo está em execução, altere o valor retornado pela propriedade Bookstore2Universal_10.BookstoreViewModel.AppName de "Bookstore2_81" para "BOOKSTORE2UNIVERSAL_10".
No momento, você pode construir e executar. Veja como nosso novo aplicativo UWP fica depois de ainda não ter feito nenhum trabalho para portá-lo para o Windows 10.
O aplicativo do Windows 10 com alterações iniciais de código-fonte em execução em um dispositivo da área de trabalho, exibição ampliada
O aplicativo do Windows 10 com alterações iniciais de código-fonte em execução em um dispositivo da área de trabalho, exibição reduzida
O modelo de exibição e as exibições ampliadas e reduzidas estão funcionando juntas corretamente, embora haja problemas que tornam isso um pouco difícil de ver. Um problema é que o SemanticZoom não rola. Isso ocorre porque, no Windows 10, o estilo padrão de um GridView faz com que ele seja disposto verticalmente (e as diretrizes de design do Windows 10 recomendam que o usemos dessa forma em aplicativos novos e portados). No entanto, as configurações de rolagem horizontal no modelo de painel de itens personalizados que copiamos do projeto Bookstore2_81 (que foi projetado para o aplicativo 8.1) estão em conflito com as configurações de rolagem vertical no estilo padrão do Windows 10 que está sendo aplicado como resultado de termos portado para um aplicativo do Windows 10. Uma segunda coisa é que o aplicativo ainda não adapta sua interface de usuário para oferecer a melhor experiência em janelas de tamanhos diferentes e em dispositivos pequenos. E, em terceiro lugar, os estilos e pincéis corretos ainda não estão sendo usados, resultando em grande parte do texto invisível (incluindo os cabeçalhos de grupo nos quais você pode clicar para diminuir o zoom). Portanto, nas próximas três seções (alterações de design SemanticZoom e GridView, interface do usuário adaptável e estilo universal), corrigiremos esses três problemas.
Alterações de design SemanticZoom e GridView
As alterações de design no Windows 10 para o controle SemanticZoom são descritas na seção Alterações de SemanticZoom. Não temos trabalho a fazer nesta seção em resposta a essas mudanças.
As alterações em GridView são descritas na seção Alterações de GridView/ListView. Temos alguns pequenos ajustes a fazer para nos adaptarmos a essas mudanças, conforme descrito abaixo.
- Em SeZoUC.xaml, em
ZoomedInItemsPanelTemplate
, definaOrientation="Horizontal"
eGroupPadding="0,0,0,20"
. - Em SeZoUC.xaml, exclua
ZoomedOutItemsPanelTemplate
e remova oItemsPanel
atributo da exibição reduzida.
Pronto!
Interface adaptável
Após essa alteração, o layout da interface do usuário que SeZoUC.xaml nos fornece é ótimo para quando o aplicativo está sendo executado em uma janela ampla (o que só é possível em um dispositivo com uma tela grande). No entanto, quando a janela do aplicativo é estreita (o que acontece em um dispositivo pequeno e também pode acontecer em um dispositivo grande), a interface do usuário que tínhamos no aplicativo da Loja do Windows Phone é indiscutivelmente mais apropriada.
Podemos usar o recurso adaptável do Visual State Manager para conseguir isso. Definiremos propriedades em elementos visuais para que, por padrão, a interface do usuário seja disposta no estado estreito usando os modelos menores que estávamos usando no aplicativo da Loja do Windows Phone. Em seguida, detectaremos quando a janela do aplicativo é mais larga ou igual a um tamanho específico (medido em unidades de pixels efetivos) e, em resposta, alteraremos as propriedades dos elementos visuais para obter um layout maior e mais amplo. Colocaremos essas alterações de propriedade em um estado visual e usaremos um gatilho adaptável para monitorar continuamente e determinar se devemos aplicar esse estado visual ou não, dependendo da largura da janela em pixels efetivos. Estamos disparando na largura da janela neste caso, mas também é possível acionar na altura da janela.
Uma largura mínima de janela de 548 epx é apropriada para este caso de uso porque esse é o tamanho do menor dispositivo em que gostaríamos de mostrar o layout amplo. Os telefones são normalmente menores que 548 epx, portanto, em um dispositivo pequeno como esse, permaneceríamos no layout estreito padrão. Em um PC, a janela será iniciada por padrão larga o suficiente para acionar a mudança para o estado amplo. A partir daí, você poderá arrastar a janela estreita o suficiente para exibir duas colunas dos itens de tamanho 250x250. Um pouco mais estreito do que isso e o gatilho será desativado, o estado visual amplo será removido e o layout estreito padrão estará em vigor.
Então, quais propriedades precisamos definir - e alterar - para obter esses dois layouts diferentes? Existem duas alternativas e cada uma implica uma abordagem diferente.
- Podemos colocar dois controles SemanticZoom em nossa marcação. Uma seria uma cópia da marcação que estávamos usando no aplicativo Windows Runtime 8.x (usando controles GridView dentro dele) e recolhida por padrão. A outra seria uma cópia da marcação que estávamos usando no aplicativo da Loja do Windows Phone (usando controles ListView dentro dele) e visível por padrão. O estado visual alternaria as propriedades de visibilidade dos dois controles SemanticZoom . Isso exigiria muito pouco esforço para ser alcançado, mas não é, em geral, uma técnica de alto desempenho. Portanto, se você usá-lo, deverá criar um perfil do seu aplicativo e verificar se ele ainda está atendendo às suas metas de desempenho.
- Podemos usar um único SemanticZoom contendo controles ListView. Para obter nossos dois layouts, no estado visual amplo, alteraríamos as propriedades dos controles ListView, incluindo os modelos aplicados a eles, para fazer com que eles sejam dispostos da mesma maneira que um GridView. Isso pode ter um desempenho melhor, mas há tantas pequenas diferenças entre os vários estilos e modelos de GridView e ListView e entre seus vários tipos de item que essa é a solução mais difícil de alcançar. Essa solução também está fortemente acoplada à maneira como os estilos e modelos padrão são projetados neste momento, dando-nos uma solução frágil e sensível a quaisquer alterações futuras nos padrões.
Neste estudo de caso, vamos com a primeira alternativa. Mas, se quiser, você pode tentar o segundo e ver se funciona melhor para você. Aqui estão as etapas a serem seguidas para implementar essa primeira alternativa.
- No SemanticZoom na marcação em seu novo projeto, defina
x:Name="wideSeZo"
eVisibility="Collapsed"
. - Volte para o projeto Bookstore2_81.WindowsPhone e abra SeZoUC.xaml. Copie a marcação do elemento SemanticZoom desse arquivo e cole-a imediatamente depois
wideSeZo
em seu novo projeto. Definax:Name="narrowSeZo"
o elemento que você acabou de colar. - Mas
narrowSeZo
precisa de alguns estilos que ainda não copiamos. Novamente no Bookstore2_81.WindowsPhone, copie os dois estilos (AuthorGroupHeaderContainerStyle
eZoomedOutAuthorItemContainerStyle
) de SeZoUC.xaml e cole-os em BookstoreStyles.xaml em seu novo projeto. - Agora você tem dois elementos SemanticZoom em seu novo SeZoUC.xaml. Envolva esses dois elementos em uma grade.
- Em BookstoreStyles.xaml em seu novo projeto, acrescente a palavra
Wide
a essas três chaves de recurso (e às suas referências em SeZoUC.xaml, mas apenas às referências dentrowideSeZo
de ):AuthorGroupHeaderTemplate
,ZoomedOutAuthorTemplate
, eBookTemplate
. - No projeto Bookstore2_81.WindowsPhone, abra BookstoreStyles.xaml. Nesse arquivo, copie esses mesmos três recursos (mencionados acima) e os dois conversores de item de lista de atalhos e a declaração de prefixo de namespace Windows_UI_Xaml_Controls_Primitives e cole-os em BookstoreStyles.xaml em seu novo projeto.
- Por fim, em SeZoUC.xaml em seu novo projeto, adicione a marcação apropriada do Visual State Manager à Grid que você adicionou acima.
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="548"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="wideSeZo.Visibility" Value="Visible"/>
<Setter Target="narrowSeZo.Visibility" Value="Collapsed"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
</Grid>
Estilo universal
Agora, vamos corrigir alguns problemas de estilo, incluindo um que introduzimos acima ao copiar do projeto antigo.
- Em MainPage.xaml, altere
LayoutRoot
o plano de fundo"{ThemeResource ApplicationPageBackgroundThemeBrush}"
de . - Em BookstoreStyles.xaml, defina o valor do recurso
TitlePanelMargin
como0
(ou qualquer valor que pareça bom para você). - Em SeZoUC.xaml, defina a Margem de
wideSeZo
como0
(ou qualquer valor que pareça bom para você). - Em BookstoreStyles.xaml, remova o atributo Margin do
AuthorGroupHeaderTemplateWide
. - Remova o atributo FontFamily de
AuthorGroupHeaderTemplate
e deZoomedOutAuthorTemplate
. - Bookstore2_81 usou as
BookTemplateTitleTextBlockStyle
chaves ,BookTemplateAuthorTextBlockStyle
ePageTitleTextBlockStyle
resource como uma indireção para que uma única chave tivesse implementações diferentes nos dois aplicativos. Não precisamos mais dessa indireção; Podemos apenas fazer referência aos estilos do sistema diretamente. Portanto, substitua essas referências em todo o aplicativo porTitleTextBlockStyle
,CaptionTextBlockStyle
eHeaderTextBlockStyle
respectivamente. Você pode usar o recurso Substituir em Arquivos do Visual Studio para fazer isso com rapidez e precisão. Em seguida, você pode excluir esses três recursos não utilizados. - Em
AuthorGroupHeaderTemplate
, substituaPhoneAccentBrush
porSystemControlBackgroundAccentBrush
e definaForeground="White"
o TextBlock para que ele pareça correto ao ser executado na família de dispositivos móveis. - Em
BookTemplateWide
, copie o atributo Foreground do segundo TextBlock para o primeiro. - Em
ZoomedOutAuthorTemplateWide
, altere a referência aSubheaderTextBlockStyle
(que agora é um pouco grande demais) para uma referência aSubtitleTextBlockStyle
. - A visualização reduzida (a lista de atalhos) não se sobrepõe mais à visualização ampliada na nova plataforma, portanto, podemos remover o
Background
atributo da visualização reduzida denarrowSeZo
. - Para que todos os estilos e modelos estejam em um arquivo, saia
ZoomedInItemsPanelTemplate
de SeZoUC.xaml e vá para BookstoreStyles.xaml.
Essa última sequência de operações de estilo deixa o aplicativo com esta aparência.
O aplicativo Windows 10 portado em execução em um dispositivo Desktop, exibição ampliada, dois tamanhos de janela
O aplicativo Windows 10 portado em execução em um dispositivo da área de trabalho, exibição reduzida, dois tamanhos de janela
O aplicativo Windows 10 portado em execução em um dispositivo móvel, exibição ampliada
O aplicativo Windows 10 portado em execução em um dispositivo móvel, exibição reduzida
Conclusão
Este estudo de caso envolveu uma interface de usuário mais ambiciosa do que a anterior. Assim como no estudo de caso anterior, esse modelo de exibição específico não exigiu nenhum trabalho e nossos esforços foram principalmente para refatorar a interface do usuário. Algumas das mudanças foram um resultado necessário da combinação de dois projetos em um, ao mesmo tempo em que suportavam muitos fatores de forma (na verdade, muito mais do que podíamos antes). Algumas das mudanças tiveram a ver com as mudanças que foram feitas na plataforma.
O próximo estudo de caso é o QuizGame, no qual analisamos o acesso e a exibição de dados agrupados.