Portabilidade do XAML e da interface do usuário do Windows Phone Silverlight para UWP
O tópico anterior foi Solução de problemas.
A prática de definir a interface do usuário na forma de marcação XAML declarativa se traduz muito bem do Windows Phone Silverlight para aplicativos da Plataforma Universal do Windows (UWP). Você descobrirá que grandes seções de sua marcação são compatíveis depois de atualizar as referências de chave de recurso do sistema, alterar alguns nomes de tipo de elemento e alterar "clr-namespace" para "using". Grande parte do código imperativo em sua camada de apresentação — modelos de exibição e código que manipula elementos de interface do usuário — também será fácil de portar.
Uma primeira olhada na marcação XAML
O tópico anterior mostrou como copiar seus arquivos XAML e code-behind para seu novo projeto do Windows 10 Visual Studio. Um dos primeiros problemas que você pode notar destacados no designer XAML do Visual Studio é que o PhoneApplicationPage
elemento na raiz do arquivo XAML não é válido para um projeto UWP (Plataforma Universal do Windows). No tópico anterior, você salvou uma cópia dos arquivos XAML que o Visual Studio gerou quando criou o projeto do Windows 10. Se você abrir essa versão de MainPage.xaml, verá que na raiz está o tipo Page, que está no namespace Windows.UI.Xaml.Controls. Portanto, você pode alterar todos os <phone:PhoneApplicationPage>
elementos para <Page>
(não se esqueça da sintaxe do elemento de propriedade) e excluir a xmlns:phone
declaração.
Para obter uma abordagem mais geral para localizar o tipo UWP que corresponde a um tipo do Windows Phone Silverlight, você pode consultar Mapeamentos de namespace e classe.
Declarações de prefixo de namespace XAML
Se você usar instâncias de tipos personalizados em suas exibições, talvez uma instância de modelo de exibição ou um conversor de valor, terá declarações de prefixo de namespace XAML em sua marcação XAML. A sintaxe deles difere entre o Windows Phone Silverlight e a UWP. Estes são alguns exemplos:
xmlns:ContosoTradingCore="clr-namespace:ContosoTradingCore;assembly=ContosoTradingCore"
xmlns:ContosoTradingLocal="clr-namespace:ContosoTradingLocal"
Altere "clr-namespace" para "using" e exclua qualquer token de assembly e ponto-e-vírgula (o assembly será inferido). O resultado será semelhante a este:
xmlns:ContosoTradingCore="using:ContosoTradingCore"
xmlns:ContosoTradingLocal="using:ContosoTradingLocal"
Você pode ter um recurso cujo tipo é definido pelo sistema:
xmlns:System="clr-namespace:System;assembly=mscorlib"
/* ... */
<System:Double x:Key="FontSizeLarge">40</System:Double>
Na UWP, omita a declaração de prefixo "System" e use o prefixo "x" (já declarado):
<x:Double x:Key="FontSizeLarge">40</x:Double>
Código imperativo
Seus modelos de exibição são um lugar onde há um código imperativo que faz referência a tipos de interface do usuário. Outro lugar são todos os arquivos code-behind que manipulam diretamente os elementos da interface do usuário. Por exemplo, você pode descobrir que uma linha de código como esta ainda não é compilada:
return new BitmapImage(new Uri(this.CoverImagePath, UriKind.Relative));
BitmapImage está no namespace System.Windows.Media.Imaging no Windows Phone Silverlight, e uma diretiva using no mesmo arquivo permite que BitmapImage seja usado sem qualificação de namespace, como no snippet acima. Em um caso como esse, você pode clicar com o botão direito do mouse no nome do tipo (BitmapImage) no Visual Studio e usar o comando Resolver no menu de contexto para adicionar uma nova diretiva de namespace ao arquivo. Nesse caso, o namespace Windows.UI.Xaml.Media.Imaging é adicionado, que é onde o tipo reside na UWP. Você pode remover a diretiva System.Windows.Media.Imaging using e isso será tudo o que é necessário para portar um código como o do snippet acima. Quando terminar, você terá removido todos os namespaces do Windows Phone Silverlight.
Em casos simples como esse, em que você está mapeando os tipos em um namespace antigo para os mesmos tipos em um novo, você pode usar o comando Localizar e Substituir do Visual Studio para fazer alterações em massa no código-fonte. O comando Resolver é uma ótima maneira de descobrir o novo namespace de um tipo. Como outro exemplo, você pode substituir todos os "System.Windows" por "Windows.UI.Xaml". Isso basicamente portará todas as diretivas using e todos os nomes de tipo totalmente qualificados que se referem a esse namespace.
Depois que todas as diretivas using antigas forem removidas e as novas adicionadas, você poderá usar o comando Organizar Usos do Visual Studio para classificar suas diretivas e remover as não utilizadas.
Às vezes, corrigir o código imperativo será tão pequeno quanto alterar o tipo de um parâmetro. Outras vezes, você precisará usar APIs do Tempo de Execução do Windows em vez de APIs do .NET para aplicativos do Tempo de Execução do Windows 8.x. Para identificar quais APIs têm suporte, use o restante deste guia de portabilidade em combinação com a visão geral dos aplicativos do .NET para Windows Runtime 8.x e a referência do Windows Runtime.
E, se você quiser apenas chegar ao estágio em que seu projeto é construído, você pode comentar ou remover qualquer código não essencial. Em seguida, itere, um problema de cada vez, e consulte os tópicos a seguir nesta seção (e no tópico anterior: Solução de problemas), até que todos os problemas de build e tempo de execução sejam resolvidos e sua portabilidade seja concluída.
Interface de usuário adaptável/responsiva
Como seu aplicativo do Windows 10 pode ser executado em uma variedade potencialmente ampla de dispositivos, cada um com seu próprio tamanho e resolução de tela, você desejará ir além das etapas mínimas para portar seu aplicativo e personalizar sua interface do usuário para ter a melhor aparência nesses dispositivos. Você pode usar o recurso Gerenciador de Estado Visual adaptável para detectar dinamicamente o tamanho da janela e alterar o layout em resposta, e um exemplo de como fazer isso é mostrado na seção Interface do usuário adaptável no tópico de estudo de caso Bookstore2.
Alarmes e lembretes
O código que usa as classes Alarm ou Reminder deve ser portado para usar a classe BackgroundTaskBuilder para criar e registrar uma tarefa em segundo plano e exibir uma notificação do sistema no momento relevante. Consulte Processamento em segundo plano e notificações do sistema.
Animação
Como uma alternativa preferencial para animações de quadro-chave e animações de/para, a biblioteca de animação UWP está disponível para aplicativos UWP. Essas animações foram projetadas e ajustadas para funcionar sem problemas, ter uma ótima aparência e fazer com que seu aplicativo pareça tão integrado ao Windows quanto os aplicativos internos. Consulte Guia de início rápido: animando sua interface do usuário usando animações de biblioteca.
Se você usar animações de quadro-chave ou animações de/para em seus aplicativos UWP, talvez queira entender a distinção entre animações independentes e dependentes que a nova plataforma introduziu. Consulte Otimizar animações e mídia. As animações executadas no thread da interface do usuário (aquelas que animam propriedades de layout, por exemplo) são conhecidas como animações dependentes e, quando executadas na nova plataforma, elas não terão efeito, a menos que você faça uma das duas coisas. Você pode redirecioná-los para animar propriedades diferentes, como RenderTransform, tornando-os independentes. Ou você pode definir EnableDependentAnimation="True"
o elemento de animação para confirmar sua intenção de executar uma animação que não pode ser garantida para ser executada sem problemas. Se você usar o Blend for Visual Studio para criar novas animações, essa propriedade será definida para você quando necessário.
Manuseio do botão Voltar
Em um aplicativo do Windows 10, você pode usar uma única abordagem para lidar com o botão Voltar e ele funcionará em todos os dispositivos. Em dispositivos móveis, o botão é fornecido para você como um botão capacitivo no dispositivo ou como um botão no invólucro. Em um dispositivo desktop, você adiciona um botão ao cromo do seu aplicativo sempre que a navegação regressiva for possível dentro do aplicativo, e isso aparece na barra de título para aplicativos em janela ou na barra de tarefas para o modo Tablet (somente Windows 10). O evento do botão Voltar é um conceito universal em todas as famílias de dispositivos, e os botões implementados no hardware ou no software geram o mesmo evento BackRequested.
O exemplo abaixo funciona para todas as famílias de dispositivos e é bom para casos em que o mesmo processamento se aplica a todas as páginas e em que você não precisa confirmar a navegação (por exemplo, para avisar sobre alterações não salvas).
// app.xaml.cs
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
[...]
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;
rootFrame.Navigated += RootFrame_Navigated;
}
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Note: On device families that have no title bar, setting AppViewBackButtonVisibility can safely execute
// but it will have no effect. Such device families provide a back button UI for you.
if (rootFrame.CanGoBack)
{
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
Windows.UI.Core.AppViewBackButtonVisibility.Visible;
}
else
{
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
Windows.UI.Core.AppViewBackButtonVisibility.Collapsed;
}
}
private void App_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
rootFrame.GoBack();
}
}
Há também uma abordagem única para todas as famílias de dispositivos para sair programaticamente do aplicativo.
Windows.UI.Xaml.Application.Current.Exit();
Associação e associações compiladas com {x:Bind}
O tópico de vinculação inclui:
- Associar um elemento de interface do usuário a "dados" (ou seja, às propriedades e comandos de um modelo de exibição)
- Associando um elemento de interface do usuário a outro elemento de interface do usuário
- Escrever um modelo de exibição observável (ou seja, ele gera notificações quando um valor de propriedade é alterado e quando a disponibilidade de um comando é alterada)
Todos esses aspectos ainda são amplamente suportados, mas há diferenças de namespace. Por exemplo, System.Windows.Data.Binding é mapeado para Windows.UI.Xaml.Data.Binding, System.ComponentModel.INotifyPropertyChanged é mapeado para Windows.UI.Xaml.Data.INotifyPropertyChanged e System.Collections.Specialized.INotifyPropertyChanged é mapeado para Windows.UI.Xaml.Interop.INotifyCollectionChanged.
As barras de aplicativos e os botões da barra de aplicativos do Windows Phone Silverlight não podem ser associados como em um aplicativo UWP. Você pode ter um código imperativo que constrói sua barra de aplicativos e seus botões, associa-os a propriedades e cadeias de caracteres localizadas e manipula seus eventos. Nesse caso, agora você tem a opção de portar esse código imperativo substituindo-o por marcação declarativa associada a propriedades e comandos e por referências de recursos estáticos, tornando seu aplicativo incrementalmente mais seguro e mais sustentável. Você pode usar o Visual Studio ou o Blend for Visual Studio para associar e estilizar botões da barra de aplicativos UWP como qualquer outro elemento XAML. Observe que, em um aplicativo UWP, os nomes de tipo que você usa são CommandBar e AppBarButton.
Os recursos relacionados à associação de aplicativos UWP atualmente têm as seguintes limitações:
- Não há suporte interno para validação de entrada de dados e as interfaces IDataErrorInfo e INotifyDataErrorInfo.
- A classe Binding não inclui as propriedades de formatação estendida disponíveis no Windows Phone Silverlight. No entanto, você ainda pode implementar IValueConverter para fornecer formatação personalizada.
- Os métodos IValueConverter usam cadeias de caracteres de idioma como parâmetros em vez de objetos CultureInfo.
- A classe CollectionViewSource não fornece suporte interno para classificação e filtragem, e o agrupamento funciona de maneira diferente. Para obter mais informações, consulte Associação de dados em profundidade e o exemplo de associação de dados.
Embora os mesmos recursos de associação ainda tenham amplo suporte, Windows 10 oferece a opção de um mecanismo de associação novo e de melhor desempenho chamado associações compiladas, que usam a extensão de marcação {x:Bind}. Consulte Associação de dados: aumentar o desempenho de seus aplicativos por meio de novos aprimoramentos na associação de dados XAML e o exemplo x:Bind.
Vinculando uma imagem a um modelo de exibição
Você pode associar a propriedade Image.Source a qualquer propriedade de um modelo de exibição do tipo ImageSource. Aqui está uma implementação típica de tal propriedade em um aplicativo do Windows Phone Silverlight:
// this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
return new BitmapImage(new Uri(this.CoverImagePath, UriKind.Relative));
Em um aplicativo UWP, você usa o esquema de URI ms-appx. Para que você possa manter o restante do seu código igual, você pode usar uma sobrecarga diferente do construtor System.Uri para colocar o esquema de URI ms-appx em um URI base e acrescentar o restante do caminho a ele. Dessa forma:
// this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
return new BitmapImage(new Uri(new Uri("ms-appx://"), this.CoverImagePath));
Dessa forma, o restante do modelo de exibição, os valores de caminho na propriedade de caminho da imagem e as associações na marcação XAML podem permanecer exatamente os mesmos.
Controles e estilos/modelos de controle
Os aplicativos do Windows Phone Silverlight usam controles definidos no namespace Microsoft.Phone.Controls e no namespace System.Windows.Controls. Os aplicativos UWP XAML usam controles definidos no namespace Windows.UI.Xaml.Controls. A arquitetura e o design dos controles XAML na UWP são praticamente os mesmos dos controles do Windows Phone Silverlight. Mas, algumas alterações foram feitas para melhorar o conjunto de controles disponíveis e unificá-los com aplicativos do Windows. Aqui estão exemplos específicos.
Nome do controle | Alterar |
---|---|
Barra de aplicativos | A propriedade Page.TopAppBar . |
ApplicationBarIconButton | O equivalente UWP é a propriedade Glyph . PrimaryCommands é a propriedade de conteúdo de CommandBar. O analisador XAML interpreta o xml interno de um elemento como o valor de sua propriedade de conteúdo. |
ApplicationBarMenuItem | O equivalente UWP é o AppBarButton.Label definido como o texto do item de menu. |
ContextMenu (no Kit de Ferramentas do Windows Phone) | Para um submenu de seleção única, use Submenu. |
Classe ControlTiltEffect.TiltEffect | As animações da biblioteca de animação UWP são incorporadas aos estilos padrão dos controles comuns. Consulte as ações do ponteiro de animação. |
LongListSelector com dados agrupados | O LongListSelector do Windows Phone Silverlight funciona de duas maneiras, que podem ser usadas em conjunto. Primeiro, ele é capaz de exibir dados agrupados por uma chave, por exemplo, uma lista de nomes agrupados por letra inicial. Em segundo lugar, ele é capaz de "ampliar" entre duas exibições semânticas: a lista agrupada de itens (por exemplo, nomes) e uma lista apenas das próprias chaves de grupo (por exemplo, letras iniciais). Com a UWP, você pode exibir dados agrupados com as Diretrizes para controles de exibição de lista e grade. |
LongListSelector com dados simples | Por motivos de desempenho, no caso de listas muito longas, recomendamos LongListSelector em vez de uma caixa de listagem do Windows Phone Silverlight, mesmo para dados simples e não agrupados. Em um aplicativo UWP, o GridView é preferencial para longas listas de itens, independentemente de os dados serem ou não passíveis de agrupamento. |
Panorama | O controle Panorama do Windows Phone Silverlight é mapeado para as Diretrizes para controles de hub em aplicativos do Tempo de Execução do Windows 8.x e Diretrizes para o controle de hub. Observe que um controle Panorama é encapsulado da última seção para a primeira e sua imagem de plano de fundo se move em paralaxe em relação às seções. As seções do cubo não são encapsuladas e a paralaxe não é usada. |
Dinâmico | O equivalente UWP do controle Pivot do Windows Phone Silverlight é Windows.UI.Xaml.Controls.Pivot. Ele está disponível para todas as famílias de dispositivos. |
Observação O estado visual do PointerOver é relevante em estilos/modelos personalizados em aplicativos do Windows 10, mas não em aplicativos do Windows Phone Silverlight. Há outros motivos pelos quais seus estilos/modelos personalizados existentes podem não ser apropriados para aplicativos do Windows 10, incluindo chaves de recursos do sistema que você está usando, alterações nos conjuntos de estados visuais usados e melhorias de desempenho feitas nos estilos/modelos padrão do Windows 10. Recomendamos que você edite uma nova cópia do modelo padrão de um controle para Windows 10 e, em seguida, aplique novamente seu estilo e personalização de modelo a ele.
Para obter mais informações sobre controles UWP, consulte Controles por função, Lista de controles e Diretrizes para controles.
Linguagem de design no Windows 10
Há algumas diferenças na linguagem de design entre os aplicativos do Windows Phone Silverlight e os aplicativos do Windows 10. Para todos os detalhes, consulte Design. Apesar das mudanças na linguagem de design, nossos princípios de design permanecem consistentes: esteja atento aos detalhes, mas sempre busque a simplicidade, concentrando-se no conteúdo e não no cromo, reduzindo ferozmente os elementos visuais e permanecendo autêntico no domínio digital; usar hierarquia visual especialmente com tipografia; design em uma grade; e dê vida às suas experiências com animações fluidas.
Localização e globalização
Para cadeias de caracteres localizadas, você pode reutilizar o arquivo .resx do seu projeto do Windows Phone Silverlight em seu projeto de aplicativo UWP. Copie o arquivo, adicione-o ao projeto e renomeie-o para Resources.resw para que o mecanismo de pesquisa o encontre por padrão. Defina Ação de Build como PRIResource e Copiar para o Diretório de Saída como Não copiar. Em seguida, você pode usar as cadeias de caracteres na marcação especificando o atributo x:Uid em seus elementos XAML. Consulte Guia de início rápido: usando recursos de cadeia de caracteres.
Os aplicativos do Windows Phone Silverlight usam a classe CultureInfo para ajudar a globalizar um aplicativo. Os aplicativos UWP usam MRT (Modern Resource Technology), que permite o carregamento dinâmico de recursos do aplicativo (localização, escala e tema) em runtime e na superfície de design do Visual Studio. Para obter mais informações, consulte Diretrizes para arquivos, dados e globalização.
O tópico ResourceContext.QualifierValues descreve como carregar recursos específicos da família de dispositivos com base no fator de seleção de recursos da família de dispositivos.
Mídia e gráficos
Ao ler sobre mídia e elementos gráficos UWP, lembre-se de que os princípios de design do Windows incentivam uma redução feroz de qualquer coisa supérflua, incluindo complexidade gráfica e desordem. O design do Windows é caracterizado por visuais limpos e claros, tipografia e movimento. Se o seu aplicativo seguir os mesmos princípios, ele se parecerá mais com os aplicativos internos.
O Windows Phone Silverlight tem um tipo RadialGradientBrush que não está presente na UWP, embora outros tipos de pincel estejam. Em alguns casos, você poderá obter um efeito semelhante com um bitmap. Observe que você pode criar um pincel de gradiente radial com Direct2D em uma UWP do Microsoft DirectX e XAML C++.
O Windows Phone Silverlight tem a propriedade System.Windows.UIElement.OpacityMask, mas essa propriedade não é membro do tipo UIElement da UWP. Em alguns casos, você poderá obter um efeito semelhante com um bitmap. E você pode criar uma máscara de opacidade com Direct2D em um aplicativo UWP C++ do Microsoft DirectX e XAML. Mas, um caso de uso comum para OpacityMask é usar um único bitmap que se adapta a temas claros e escuros. Para gráficos vetoriais, você pode usar pincéis de sistema com reconhecimento de tema (como os gráficos de pizza ilustrados abaixo). Mas, para criar um bitmap com reconhecimento de tema (como as marcas de seleção ilustradas abaixo), é necessária uma abordagem diferente.
Em um aplicativo do Windows Phone Silverlight, a técnica é usar uma máscara alfa (na forma de um bitmap) como OpacityMask para um retângulo preenchido com o pincel de primeiro plano:
<Rectangle Fill="{StaticResource PhoneForegroundBrush}" Width="26" Height="26">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="/Assets/wpsl_check.png"/>
</Rectangle.OpacityMask>
</Rectangle>
A maneira mais direta de portar isso para um aplicativo UWP é usar um BitmapIcon, como este:
<BitmapIcon UriSource="Assets/winrt_check.png" Width="21" Height="21"/>
Aqui, winrt_check.png é uma máscara alfa na forma de um bitmap, assim como wpsl_check.png é, e pode muito bem ser o mesmo arquivo. No entanto, talvez você queira fornecer vários tamanhos diferentes de winrt_check.png a serem usados para diferentes fatores de dimensionamento. Para obter mais informações sobre isso e para obter uma explicação das alterações nos valores de Largura e Altura , consulte Exibir ou pixels efetivos, distância de exibição e fatores de escala neste tópico.
Uma abordagem mais geral, que é apropriada se houver diferenças entre a forma de tema claro e escuro de um bitmap, é usar dois ativos de imagem: um com um primeiro plano escuro (para tema claro) e outro com um primeiro plano claro (para tema escuro). Para obter mais detalhes sobre como nomear esse conjunto de ativos de bitmap, consulte Personalizar seus recursos para idioma, escala e outros qualificadores. Uma vez que um conjunto de arquivos de imagem é nomeado corretamente, você pode se referir a eles no resumo, usando seu nome raiz, assim:
<Image Source="Assets/winrt_check.png" Stretch="None"/>
No Windows Phone Silverlight, a propriedade UIElement.Clip pode ser qualquer forma que você possa expressar com uma geometria e normalmente é serializada na marcação XAML na minilinguagem StreamGeometry . Na UWP, o tipo da propriedade Clip é RectangleGeometry, portanto, você só pode recortar uma região retangular. Permitir que um retângulo seja definido usando a minilinguagem seria muito permissivo. Portanto, para portar uma região de recorte na marcação, substitua a sintaxe do atributo Clip e transforme-a em uma sintaxe de elemento de propriedade semelhante à seguinte:
<UIElement.Clip>
<RectangleGeometry Rect="10 10 50 50"/>
</UIElement.Clip>
Observe que você pode usar geometria arbitrária como uma máscara em uma camada com Direct2D em um aplicativo UWP Microsoft DirectX e XAML C++.
Navegação
Ao navegar até uma página em um aplicativo do Windows Phone Silverlight, você usa um esquema de endereçamento URI (Uniform Resource Identifier):
NavigationService.Navigate(new Uri("/AnotherPage.xaml", UriKind.Relative)/*, navigationState*/);
Em um aplicativo UWP, você chama o método Frame.Navigate e especifica o tipo da página de destino (conforme definido pelo atributo x:Class da definição de marcação XAML da página):
// In a page:
this.Frame.Navigate(typeof(AnotherPage)/*, parameter*/);
// In a view model, perhaps inside an ICommand implementation:
var rootFrame = Windows.UI.Xaml.Window.Current.Content as Windows.UI.Xaml.Controls.Frame;
rootFrame.Navigate(typeof(AnotherPage)/*, parameter*/);
Você define a página de inicialização de um aplicativo do Windows Phone Silverlight em WMAppManifest.xml:
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
Em um aplicativo UWP, você usa o código imperativo para definir a página de inicialização. Aqui está um código do App.xaml.cs que ilustra como:
if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
O mapeamento de URI e a navegação de fragmentos são técnicas de navegação de URI e, portanto, não são aplicáveis à navegação UWP, que não se baseia em URIs. O mapeamento de URI existe em resposta à natureza fracamente tipada de identificar uma página de destino com uma cadeia de caracteres de URI, o que leva a problemas de fragilidade e manutenção caso a página seja movida para uma pasta diferente e, portanto, para um caminho relativo diferente. Os aplicativos UWP usam navegação baseada em tipo, que é fortemente tipada e verificada pelo compilador, e não tem o problema que o mapeamento de URI resolve. O caso de uso da navegação de fragmentos é passar algum contexto para a página de destino para que a página possa fazer com que um fragmento específico de seu conteúdo seja exibido ou exibido de outra forma. O mesmo objetivo pode ser alcançado passando um parâmetro de navegação quando você chama o método Navigate.
Para obter mais informações, consulte Navegação.
Referência de chave de recurso
A linguagem de design evoluiu para o Windows 10 e, consequentemente, certos estilos de sistema foram alterados e muitas chaves de recursos do sistema foram removidas ou renomeadas. O editor de marcação XAML no Visual Studio realça referências a chaves de recurso que não podem ser resolvidas. Por exemplo, o editor de marcação XAML sublinhará uma referência à chave PhoneTextNormalStyle
de estilo com um rabisco vermelho. Se isso não for corrigido, o aplicativo será encerrado imediatamente quando você tentar implantá-lo no emulador ou no dispositivo. Portanto, é importante atender à correção da marcação XAML. E você descobrirá que o Visual Studio é uma ótima ferramenta para detectar esses problemas.
Além disso, veja Texto, abaixo.
Barra de status (bandeja do sistema)
A bandeja do sistema (definida na marcação XAML com shell:SystemTray.IsVisible
) agora é chamada de barra de status e é mostrada por padrão. Você pode controlar sua visibilidade no código imperativo chamando os métodos Windows.UI.ViewManagement.StatusBar.ShowAsync e HideAsync.
Texto
O texto (ou tipografia) é um aspecto importante de um aplicativo UWP e, durante a portabilidade, talvez você queira revisitar os designs visuais de seus modos de exibição para que eles estejam em harmonia com a nova linguagem de design. Use essas ilustrações para localizar os estilos de sistema UWP TextBlock disponíveis. Encontre aqueles que correspondem aos estilos do Windows Phone Silverlight que você usou. Como alternativa, você pode criar seus próprios estilos universais e copiar as propriedades dos estilos do sistema Windows Phone Silverlight para eles.
Estilos de TextBlock do sistema para aplicativos do Windows 10
Em um aplicativo do Windows Phone Silverlight, a família de fontes padrão é Segoe WP. Em um aplicativo do Windows 10, a família de fontes padrão é Segoe UI. Como resultado, as métricas de fonte em seu aplicativo podem parecer diferentes. Se você quiser reproduzir a aparência do texto do Windows Phone Silverlight, poderá definir suas próprias métricas usando propriedades como LineHeight e LineStackingStrategy. Para obter mais informações, consulte Diretrizes para fontes e Criar aplicativos UWP.
Mudanças de tema
Para um aplicativo do Windows Phone Silverlight, o tema padrão é escuro por padrão. Para dispositivos Windows 10, o tema padrão foi alterado, mas você pode controlar o tema usado declarando um tema solicitado em App.xaml. Por exemplo, para usar um tema escuro em todos os dispositivos, adicione RequestedTheme="Dark"
ao elemento Application raiz.
Blocos
Os blocos para aplicativos UWP têm comportamentos semelhantes aos blocos dinâmicos para aplicativos do Windows Phone Silverlight, embora haja algumas diferenças. Por exemplo, o código que chama o método Microsoft.Phone.Shell.ShellTile.Create para criar blocos secundários deve ser portado para chamar SecondaryTile.RequestCreateAsync. Aqui está um exemplo de antes e depois, primeiro a versão do Windows Phone Silverlight:
var tileData = new IconicTileData()
{
Title = this.selectedBookSku.Title,
WideContent1 = this.selectedBookSku.Title,
WideContent2 = this.selectedBookSku.Author,
SmallIconImage = this.SmallIconImageAsUri,
IconImage = this.IconImageAsUri
};
ShellTile.Create(this.selectedBookSku.NavigationUri, tileData, true);
E o equivalente UWP:
var tile = new SecondaryTile(
this.selectedBookSku.Title.Replace(" ", string.Empty),
this.selectedBookSku.Title,
this.selectedBookSku.ArgumentString,
this.IconImageAsUri,
TileSize.Square150x150);
await tile.RequestCreateAsync();
O código que atualiza um bloco com o método Microsoft.Phone.Shell.ShellTile.Update ou a classe Microsoft.Phone.Shell.ShellTileSchedule deve ser portado para usar as classes TileUpdateManager, TileUpdater, TileNotification e/ou ScheduledTileNotification.
Para obter mais informações sobre blocos, notificações do sistema, selos, faixas e notificações, consulte Criando blocos e Trabalhando com blocos, selos e notificações do sistema. Para obter detalhes sobre os tamanhos dos ativos visuais usados para blocos UWP, consulte Blocos e ativos visuais do sistema.
Brindes
O código que exibe uma notificação do sistema com a classe Microsoft.Phone.Shell.ShellToast deve ser portado para usar as classes ToastNotificationManager, ToastNotifier, ToastNotification e/ou ScheduledToastNotification. Observe que, em dispositivos móveis, o termo voltado para o consumidor para "brinde" é "banner".
Consulte Trabalhando com blocos, selos e notificações do sistema.
Pixels de exibição ou efetivos, distância de visualização e fatores de escala
Os aplicativos do Windows Phone Silverlight e os aplicativos do Windows 10 diferem na maneira como abstraem o tamanho e o layout dos elementos da interface do usuário do tamanho físico real e da resolução dos dispositivos. Um aplicativo do Windows Phone Silverlight usa pixels de exibição para fazer isso. Com o Windows 10, o conceito de pixels de exibição foi refinado para o de pixels efetivos. Aqui está uma explicação desse termo, o que ele significa e o valor extra que ele oferece.
O termo "resolução" refere-se a uma medida de densidade de pixels e não, como comumente se pensa, à contagem de pixels. "Resolução efetiva" é a maneira como os pixels físicos que compõem uma imagem ou glifo são resolvidos a olho nu, dadas as diferenças na distância de visualização e no tamanho físico do pixel do dispositivo (a densidade de pixels é o recíproco do tamanho físico do pixel). A resolução efetiva é uma boa métrica para criar uma experiência porque é centrada no usuário. Ao entender todos os fatores e controlar o tamanho dos elementos da interface do usuário, você pode tornar a experiência do usuário boa.
Para um aplicativo do Windows Phone Silverlight, todas as telas do telefone têm exatamente 480 pixels de exibição, sem exceção, independentemente de quantos pixels físicos a tela tenha, nem qual seja sua densidade de pixels ou tamanho físico. Isso significa que um elemento Image terá Width="48"
exatamente um décimo da largura da tela de qualquer telefone que possa executar o aplicativo Windows Phone Silverlight.
Para um aplicativo do Windows 10, não é o caso de todos os dispositivos terem um número fixo de pixels efetivos de largura. Isso provavelmente é óbvio, dada a ampla variedade de dispositivos em que um aplicativo UWP pode ser executado. Dispositivos diferentes têm um número diferente de pixels efetivos de largura, variando de 320 epx para os menores dispositivos a 1024 epx para um monitor de tamanho modesto e muito além de larguras muito maiores. Tudo o que você precisa fazer é continuar a usar elementos dimensionados automaticamente e painéis de layout dinâmicos como sempre fez. Também haverá alguns casos em que você definirá as propriedades dos elementos da interface do usuário como um tamanho fixo na marcação XAML. Um fator de escala é aplicado automaticamente ao seu aplicativo, dependendo do dispositivo em que ele é executado e das configurações de exibição feitas pelo usuário. E esse fator de escala serve para manter qualquer elemento da interface do usuário com um tamanho fixo apresentando um destino de toque (e leitura) de tamanho mais ou menos constante para o usuário em uma ampla variedade de tamanhos de tela. E junto com o layout dinâmico, sua interface do usuário não será apenas dimensionada opticamente em diferentes dispositivos, mas fará o que for necessário para ajustar a quantidade apropriada de conteúdo ao espaço disponível.
Como 480 era anteriormente a largura fixa em pixels de exibição para uma tela do tamanho de um telefone, e esse valor agora é normalmente menor em pixels efetivos, uma regra geral é multiplicar qualquer dimensão na marcação do aplicativo Windows Phone Silverlight por um fator de 0,8.
Para que seu aplicativo tenha a melhor experiência em todas as exibições, recomendamos que você crie cada ativo de bitmap em uma variedade de tamanhos, cada um adequado para um fator de escala específico. Fornecer ativos em escala de 100%, 200% e 400% (nessa ordem de prioridade) fornecerá excelentes resultados na maioria dos casos em todos os fatores de escala intermediários.
Observação Se, por qualquer motivo, você não puder criar ativos em mais de um tamanho, crie ativos em escala de 100%. No Microsoft Visual Studio, o modelo de projeto padrão para aplicativos UWP fornece ativos de identidade visual (imagens de bloco e logotipos) em apenas um tamanho, mas eles não são 100% em escala. Ao criar ativos para seu próprio aplicativo, siga as diretrizes nesta seção e forneça tamanhos de 100%, 200% e 400% e use pacotes de ativos.
Se você tiver obras de arte complexas, convém fornecer seus ativos em ainda mais tamanhos. Se você está começando com arte vetorial, é relativamente fácil gerar ativos de alta qualidade em qualquer fator de escala.
Não recomendamos que você tente dar suporte a todos os fatores de escala, mas a lista completa de fatores de escala para aplicativos do Windows 10 é 100%, 125%, 150%, 200%, 250%, 300% e 400%. Se você fornecê-los, a Loja escolherá os ativos de tamanho correto para cada dispositivo e somente esses ativos serão baixados. A Loja seleciona os ativos a serem baixados com base no DPI do dispositivo.
Para obter mais informações, consulte Design responsivo 101 para aplicativos UWP.
Tamanho da janela
Em seu aplicativo UWP, você pode especificar um tamanho mínimo (largura e altura) com código imperativo. O tamanho mínimo padrão é 500x320epx e esse também é o menor tamanho mínimo aceito. O maior tamanho mínimo aceito é 500x500epx.
Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().SetPreferredMinSize
(new Size { Width = 500, Height = 500 });
O próximo tópico é Portabilidade para E/S, dispositivo e modelo de aplicativo.