Modelo de navegação (C#/VB/C++ e XAML)

O modelo de navegação usado nos modelos de projeto de Aplicativos Hub, de Grade e Dividido é o modelo de navegação recomendado para aplicativos da Windows Store compilados em XAML. Esse modelo cria um quadro central como o conteúdo da janela padrão e os usuários navegam para outras páginas usando esse quadro. O modelo de navegação de quadro único oferece uma transição suave entre as páginas e também facilita o gerenciamento de estados. Para saber mais sobre a navegação e obter um exemplo do uso da navegação interna em um aplicativo da Windows Store compilado em XAML, veja Guia de início rápido: usando a navegação de página única.

Importante  As informações deste tópico foram atualizadas para o Microsoft Visual Studio 2013.

O arquivo App.xaml.cs/vb/cpp cria um Frame, caso ainda não exista, e torna o Frame como o conteúdo da janela atual. Se o conteúdo do quadro for nulo, o aplicativo navegará para a home page, conforme especificado no App.xaml code behind. Por exemplo, no Aplicativo de Grade, o código é rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups") ).

Durante a instalação, o SuspensionManager registra o Frame. SuspensionManager é uma classe auxiliar fornecida na pasta Comum no modelo de Aplicativo de Grade ou Aplicativo Dividido e fornece a implementação usada para armazenar e carregar o estado quando o aplicativo é encerrado.

Todos os aplicativos se movem por meio de um ciclo de vida de aplicativo como ditado pelo sistema operacional. Sempre que um aplicativo é encerrado pelo sistema por motivos, como restrições de recursos, desligamentos, reinicializações, etc., você como o desenvolvedor deve restaurar os dados após reiniciar o aplicativo. SuspensionManager é fornecido para ajudá-lo com essa tarefa.

SuspensionManager captura o estado de sessão global para simplificar o gerenciamento do tempo de vida do processo de um aplicativo. O estado da sessão é automaticamente desmarcado sob uma variedade de condições e deve ser usado apenas para armazenar informações que seria conveniente carregadas em sessões, mas que deve ser descartado quando um aplicativo trava ou é atualizado. Basicamente, isso inclui dados transitórios de interface do usuário.

SuspensionManager tem duas propriedades: SessionState e KnownTypes.

  • SessionState fornece acesso ao estado de sessão global para a sessão atual. Este estado é serializado pelo método SaveAsync e é restaurado pelo método RestoreAsync. Todos os dados são salvos e restaurados usando DataContractSerialization e devem ser os mais compactos possível. Cadeias de caracteres são outros tipos de dados independentes que são fortemente recomendados.
  • KnownTypes armazena uma lista de tipos personalizados para o DataContractSerializer que é usado pelos métodos SaveAsync e RestoreAsync ao ler e gravar o estado de sessão. Inicialmente, tipos vazios adicionais podem ser adicionados para personalizar o processo de serialização.

SuspensionManager armazena o estado em um dicionário, SessionState. O dicionário armazena FrameState em relação a uma chave que está exclusivamente associada a um Frame. Cada dicionário FrameState mantém o estado de cada página no estado de navegação para o quadro específico. Cada página armazena o parâmetro de navegação, bem como qualquer outro estado que o usuário decida adicionar.

É assim que funciona: quando um Frame é criado, se você deseja que o estado seja armazenado para esse quadro, ele deve ser imediatamente registrado. Eles são registrados com a chamada (SuspensionManager.RegisterFrame(rootFrame, "AppFrame")) a seguir. Cada quadro deve ter uma chave exclusiva associada a ele. Geralmente a maioria dos aplicativos só tem um único quadro. Se você declarar um segundo quadro, ele precisará ser registrado também. Quando um quadro é registrado, duas propriedades anexadas são definidas no quadro. A primeira é a chave que você associou ao quadro e a segunda é o dicionário de estado de sessão que será associado ao quadro. Os quadros que foram registrados anteriormente terão sua navegação e seu estado imediatamente restaurados. Quadros também podem ser cancelados; todo o estado e o histórico de navegação serão descartados.

E agora para chamadas importantes: SaveAsync e RestoreAsync. SaveAsync é usada para salvar o SessionState inteiro. Todos os quadros que foram registrados por meio do SuspensionManager.RegisterFrame também preservarão sua pilha de navegação atual, que por sua vez proporciona à sua página ativa a oportunidade de salvar seus dados. O SessionState é então serializado usando um DataContractSerializer e gravado em um arquivo armazenado na pasta local, conforme definido pelo ApplicationData.

RestoreAsync é usada para ler o SessionState salvo anteriormente. Todos os quadros que foram registrados por meio do RegisterFrame também restaurarão seu estado de navegação anterior, que proporcionará à sua página ativa a oportunidade de restaurar seu estado. Novamente como na SaveAsync, um DataContractSerializer é usado para desserializar o estado armazenado em um arquivo na pasta local do Aplicativo.

Há dois erros comuns que as pessoas cometem ao tentar armazenar o estado do seu aplicativo.

  • Os tipos armazenados por páginas individuais devem ser capazes de serem serializados pelo DataContractSerializer em C# e VB. Para fazer isso, qualquer tipo personalizado deve ser registrado antes de poder ser salvo ou restaurado. SuspensionManager fornece a coleção de KnownTypes que passa os tipos na coleção para o DataContractSerializer. Conforme o SuspensionManager é chamado para restaurar o estado na substituição de OnLaunched do code-behind por App.xaml, um bom lugar para registrar tipos é o construtor de aplicativo.

            public App()
            {
                this.InitializeComponent();
                this.Suspending += OnSuspending;
                SuspensionManager.KnownTypes.Add(typeof(MyCustomType));
            }
    
  • Os parâmetros passados no uso da navegação devem ser capazes de ser serializados pela plataforma. Quando estamos salvando e restaurando a pilha de navegação, chamamos Frame.GetNavigationState() e Frame.SetNavigationState(). Ambas essas chamadas fazem uso de um formato de serialização interno e todos os tipos passados como o parâmetro em Frame.Navigate() devem ser capazes de serem serializados pela plataforma.

O uso de SuspensionManager está envolvido na implementação da NavigationHelper.

NavigationHelper é uma implementação de uma página que fornece as seguintes conveniências importantes:

  • Manipuladores de eventos para GoBack, GoForward e GoHome.
  • Atalhos de teclado e mouse para navegação.
  • Gerenciamento de estado para navegação e gerenciamento do tempo de vida do processo.

Modelo de exibição padrão

O DefaultViewModel é usado em cada Modelo de Item de Página Complexa. O DataContext é associado ao DefaultViewModel definido na própria página: DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}". A propriedade DefaultViewModel é do tipo ObservableDictionary, que é um mapa das cadeias de caracteres (chaves) para objetos (valores). O DefaultViewModel é fornecido como uma conveniência, mas, se necessário, pode ser substituído por um modelo de exibição fortemente tipado, se necessário.

Cada página está associada às propriedades que se destinam a serem definidas no DefaultViewModel no code-behind. Tomemos por exemplo a GroupedItemsPage. Nesta página, a CollectionViewSource tem a propriedade Source associada aos Grupos de propriedade (Source="{Binding Groups}". Grupos são uma chave de um par de chave,valor armazenado no DefaultViewModel (this.DefaultViewModel["Groups"] = sampleDataGroups;).

Estado de exibição do aplicativo para mapeamento do estado visual

Nos modelos fornecidos para o Windows 8, LayoutAwarePage fornecia um código para lidar com o estado do modo de exibição, mas esse código não é mais necessário no Windows 8.1. Somente SplitPage e FileOpenPicker incluem código para lidar com o estado do modo de exibição. Espera-se, agora, que cada página lide com todos os tamanhos de janela, desde que a largura seja de pelo menos 500 px.

NavigationHelper registra comandos para GoBack e GoForward. Essas implementações verificam se há um Frame associado à página e, caso haja, se o quadro pode voltar ou avançar antes de chamar Frame.GoBack() ou Frame.GoForward(). Isso pode ser substituído para mudar o comportamento padrão, tal como ocorre na Página de Divisão.

NavigationHelper também registra os atalhos comuns de mouse e teclado, que são normalmente usados para navegação. O botão para voltar do mouse, "ALT + tecla de seta para a esquerda" e a tecla voltar do teclado são usadas para navegar de volta. O botão para avançar do mouse, "ALT + tecla de seta para a direita" e a tecla avançar do teclado são usadas para navegar avante.

Gerenciamento do Tempo de Vida do Processo

Além de fornecer a implementação descrita anteriormente, NavigationHelper também precisa ser chamado nos manipuladores de eventos OnNavigatedTo() e OnNavigatedFrom(), que são implementados em cada página. Quando esses eventos ocorrem, o NavigationHelper chama uma implementação específica de página de LoadState() e SaveState(). Você pode personalizar a implementação dessas funções em cada página. Elas devem ser usadas no lugar de OnNavigatedTo() e OnNavigatedFrom(), respectivamente.

OnNavigatedFrom() é chamado quando a página está para ser exibida em um Frame. Ao navegar para uma nova página, carregamos o estado associado à página. Se a página está sendo restaurada, o estado em que a página foi salva anteriormente é restaurado. LoadState é então chamado de tal forma que cada página possa reagir. LoadState tem dois parâmetros; o parâmetro de navegação original passado para OnNavigateTo e o estado da página anterior, se houver.

OnNavigatedFrom() é chamado quando a página não vai mais ser exibida em um Frame. Ao navegar para sair de uma página, permitimos que a página salve seu respectivo estado atual. Um dicionário vazio é passado para SaveState(). Cada página pode substituir os objetos SaveState e de repositório no dicionário com chave (cadeia de caracteres para objeto). Esse dicionário é então associado à página e adicionado ao SessionState que o SuspensionManager acompanha para um determinado quadro.

Observação  

  • Todos os dados que são armazenados na página individual devem estar disponíveis para serem serializados pelo DataContractSerializer. Para saber mais, veja a discussão do SuspensionManager no início desse tópico.
  • Também é importante armazenar somente informações de interface do usuário transitórias aqui, porque este estado será perdido se o aplicativo for fechado por qualquer meio que não seja Encerrado.

Estrutura de um aplicativo

Para compreender a estrutura de um aplicativo, usaremos um aplicativo criado com o modelo de projeto de Aplicativo de Grade. O ponto de partida de todos os aplicativos da Windows Store que usam XAML é o objeto Application em App.xaml e o code-behind associado. O primeiro código que é executado quando o aplicativo criado é o construtor de aplicativo. A seguir, um dos vários métodos de ativação é chamado; nesse caso, será o evento OnLaunched quando o aplicativo é inicializado de um bloco na tela inicial. Nessa chamada, um Frame é criado, qualquer estado anterior é recarregado (se o aplicativo foi encerrado anteriormente) e o quadro é usado para navegar para a primeira página. Quando navegamos para uma página, o manipulador de eventos OnNavigatedTo na página chama NavigationHelper. O NavigationHelper executa e registra os parâmetros e recarrega todas as informações de estado anterior da página em questão. Então, chama o método LoadState() que foi substituído em GroupedItemsPage. Aqui, os dados são carregados e o modelo de exibição padrão é preenchido. Quando navegamos para outra página, o manipulador de eventos OnNavigatedFrom chama NavigationHelper, que salva qualquer estado dessa página chamando SaveState(). SaveState() é substituído em páginas que têm estado transitório de interface do usuário, como a SplitPage, antes de navegar para a nova página e depois chamar novamente usando o método LoadState().

Tópicos relacionados

Modelos de projeto C#, VB e C++ para aplicativos da Windows Store

Parte 2: gerenciar o ciclo de vida e o estado do aplicativo

Parte 3: navegação, layout e modos de exibição