01. Installer et paramétrer Navegar

Update : cette série de tutoriaux vaut également pour la version Windows 10, la seule différence étant la struture du projet qui est unique pour Windows 10

Afin de mieux se familiariser avec Navegar, nous allons voir ensemble une série d'articles permettant sa mise en place et son utilisation à travers un exemple d'application universelle Windows 8.1 et Windows Phone 8.1. Nous allons donc réaliser pas à pas une application CRM permettant la gestion des clients et de leurs commandes associées.
Voici la liste des articles qui constituent cette série d'articles :


Vous pouvez retrouver l'exemple qui va nous servir dans ces tutoriaux sur le site de Navegar, dans la partie code source sous le nom Navegar.UAP.Exemple.CRM


1. Création des projets

Commençons par créer un projet de type Universal App. Visual Studio va générer 3 projets (ou un seul pour Windows 10) :
  • Un projet Windows 8.1 qui sera le projet Modern UI
  • Un projet Windows Phone 8.1
  • Un Shared Project qui va contenir l'ensemble des classes et ressources communes aux 2 projets
Une fois ces projets créés on va pouvoir installer Navegar dans les projet Windows 8.1 et WP 8.1, pour cela utilisez soit la console de gestionnaire de paquet de NuGet et lancez la commande install-package Navegar, soit faites un clic droit sur les références de chaque projet (sauf le Shared Project) et installez Navegar.
Navegar dépendant de MvvmLightLibs, ce paquet sera installé mais il faudra également installer MvvmLight complet afin d'avoir la structure de MvvmLight. Navegar n'installe pas MvvmLight complet car il peut être utilisé dans une librairie qui n'a pas besoin de la version complète de MvvmLight.

2. Stucture des projets
Nous allons structurer les projets de la façon suivante :



Vous pouvez voir que tout ou presque est partagé dans le Shared Project, notamment une classe ViewModelServices.cs dans laquelle une propriété NavigationService permettra d'appeler, de façon simple, la navigation au sein de l'application. Cette classe sera donc héritée par tous nos ViewModel.



/// <summary>
/// Permet de retourner l'instance en cours de la navigation Navegar
/// </summary>
public INavigation NavigationService
{
    get { return SimpleIoc.Default.GetInstance<INavigation>(); }
}



3. Préparation de la classe de navigation
La première chose à faire sera d'enregistrer la classe de navigation dans l'IOC de MvvmLight avec l'interface. Pour cela ajoutez ceci au constructeur du ViewModelLocator :

//Si le service de navigation n'est pas enregistré dans l'IOC
if (!SimpleIoc.Default.IsRegistered<INavigation>())
{
    SimpleIoc.Default.Register<INavigation, Navigation>();
}


Ensuite il faut associer les ViewModels avec les View qui leur correspondent, de cette façon lorsque Navegar fera l'instanciation du ViewModel à la navigation, la classe lancera également la navigation vers la View voulue. Pour réaliser cette association, on ajoute au constructeur du ViewModelLocator la ligne suivante (pour la page LandingPage, qui sera notre première page lancée dans l'application) :

//Association des ViewModels et des Views associées
SimpleIoc.Default.GetInstance<INavigation>().RegisterView<LandingPageViewModel, LandingPage>();


Voila ce à quoi notre ViewModelLocator ressemble :

/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    //Si le service de navigation n'est pas enregistré dans l'IOC
    if (!SimpleIoc.Default.IsRegistered<INavigation>())
    {
        SimpleIoc.Default.Register<INavigation>();
    }

    //Association des ViewModels et des Views associées
    SimpleIoc.Default.GetInstance<INavigation>().RegisterView<LandingPageViewModel, LandingPage>();
    SimpleIoc.Default.GetInstance<INavigation>().RegisterView<ClientPageViewModel, ClientPage>();
    SimpleIoc.Default.GetInstance<INavigation>().RegisterView<ListClientsPageViewModel, ListClientsPage>();
    SimpleIoc.Default.GetInstance<INavigation>().RegisterView<CommandePageViewModel, CommandePage>();
    SimpleIoc.Default.GetInstance<INavigation>().RegisterView<ListCommandesPageViewModel, ListCommandesPage>();
}


Afin d'associer à chaque View le datacontext qui correspond au ViewModel Navegar met à disposition une fonction permettant de récupérer l'instance du ViewModel en cours dans la navigation. Pour cela dans la classe ViewModelLocator vous devez définir des propriétés correspondants au ViewModels utilisés :

public LandingPageViewModel LandingPageViewModelInstance
{
    get { return SimpleIoc.Default.GetInstance<INavigation>().GetViewModelInstance<LandingPageViewModel>(); }
}


Faites ceci pour chaque instance de ViewModel que vous avez à créer et ajoutez cette propriété comme datacontext de la View. Pour rappel voici la syntaxe que vous pouvez utiliser pour effectuer cela :

<Page.DataContext>
    <Binding Path="LandingPageViewModelInstance" Source="{StaticResource Locator}"/>
</Page.DataContext>


4. Fin de la préparation et navigation vers la page LandingPage
Il nous reste maintenant à initialiser la navigation et naviguer vers la première page de notre application.
Pour cela il nous faut modifier la fonction OnLaunched du fichier App.xaml.cs. La fonction devra ressembler à cela :

/// <summary>
/// Invoked when the application is launched normally by the end user.  Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
    if (System.Diagnostics.Debugger.IsAttached)
    {
        this.DebugSettings.EnableFrameRateCounter = true;
    }
#endif

    Frame rootFrame = Window.Current.Content as Frame;
    
    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();
        
        // TODO: change this value to a cache size that is appropriate for your application
        rootFrame.CacheSize = 1;

        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            // TODO: Load state from previously suspended application
        }

        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }

    if (rootFrame.Content == null)
    {
#if WINDOWS_PHONE_APP
        // Removes the turnstile navigation for startup.
        if (rootFrame.ContentTransitions != null)
        {
             this.transitions = new TransitionCollection();
             foreach (var c in rootFrame.ContentTransitions)
             {
                  this.transitions.Add(c);
             }
         }

         rootFrame.ContentTransitions = null;
         rootFrame.Navigated += this.RootFrame_FirstNavigated;
#endif
         //Initialisation et navigation vers la premiére page de l'application
         SimpleIoc.Default.GetInstance<INavigation>().InitializeRootFrame(rootFrame);
         if (string.IsNullOrEmpty(SimpleIoc.Default.GetInstance<INavigation>().NavigateTo<LandingPageViewModel>(true)))
         {
             throw new Exception("Failed to create initial page");
         }
    }

    // Ensure the current window is active
    Window.Current.Activate();
}


Nous pouvons observer plusieurs choses dans cette fonction.
Tout d'abord l'ajout d'une ligne :

SimpleIoc.Default.GetInstance<INavigation>().InitializeRootFrame(rootFrame);

La fonction InitializeRootFrame que l'on voit ici permet d'indiquer à Navegar quel sera l'objet Frame qui servira l'affichage et la pile de navigation de l'application.
Puis juste en dessous une modification. En effet si vous avez observé le code généré par Visual Studio, la fonction OnLaunched posséde une ligne permettant de lancer la première page de l'application :

if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
{
    throw new Exception("Failed to create initial page");
}


Il suffit simplement de remplacer l'instruction

!rootFrame.Navigate(typeof(MainPage), e.Arguments)


par l'instruction de Navegar

!string.IsNullOrEmpty(SimpleIoc.Default.GetInstance<INavigation>().NavigateTo<LandingPageViewModel>(true))


pour naviguer vers la première page qui est LandingPage.

Si l'on détaille l'instruction on peut voir que celle-çi renvoi un string contenant en fait la clé unique de l'instance de LandingPageViewModel généré par Navegar, si cette valeur est vide ou nulle la navigation n'a pas pu s’effectuer correctement, il faut donc en aviser l'utilisateur.

De plus on peut voir que lors de l'appel à la fonction NavigateTo on indique le ViewModel vers lequel l'on souhaite naviguer et on passe en paramètre une valeur booléenne indiquant que l'on souhaite lancer une nouvelle instance de ce ViewModel (par défaut à false). Si vous avez déja jeté un oeil à la documentation de Navegar vous avez pu remarquer que le premier paramètre de la fonction NavigateTo peut être une instance de type ViewModelBase. Ce paramètre permet d'indiquer que l'on souhaite pouvoir revenir, lors d'une navigation inverse, sur un ViewModel en particulier (le plus souvent celui où l'on se trouve, on indiquera alors this en tant qu'argument de la fonction NavigateTo). Ici nous ne souhaitons pas revenir sur la classe et de plus celle-çi n'hérite pas de ViewModelBase elle serait donc incompatible.

Voila votre application est maintenant prête pour la navigation. Rassurez-vous nous verrons différents paramètres possibles de la fonction NavigateTo dans les articles suivants.

// coding with fun

Écrire un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec une *

Quelle est la deuxième lettre du mot esonb ? :