Question

Je cherche un moyen de naviguer entre les écrans de mon application.Fondamentalement, ce que j'ai vu jusqu'à présent consiste à transmettre un URI de chaîne au NavigationService, complété par des paramètres de chaîne de requête., par exemple.

NavigationService.Navigate(new Uri("/MainPage.xaml?selectedItem=" +bookName.Id, UriKind.Relative));

Mais en fin de compte, cela ne me plaît pas vraiment, car cela nécessite des cordes magiques, et elles peuvent entraîner des problèmes plus tard.

Idéalement, je créerais simplement une instance de la classe vers laquelle je souhaite accéder, en passant les paramètres comme arguments au constructeur.Est-ce possible?Si c'est le cas, comment?

Était-ce utile?

La solution

Bien que la navigation effective devra utiliser des chaînes éventuellement, vous pouvez créer ou utiliser une enveloppe de sécurité.

Je suggérerais de regarder Caliburn Micro Même si vous l'utilisez uniquement pour la navigation de type Safe. Voici un snippet d'un tutoriel sur l'utilisation de WP8 :

Le navigagerservice qui est livré avec la boîte à outils prend en charge un modèle modèle d'affichage au lieu de déclarer quelle est l'URL de la page où nous souhaitons prendre l'utilisateur (c'est l'approche standard), nous Déclarez qui est la viewModel que nous voulons afficher. Le service veillera à créer l'URL correcte et à afficher la vue associée au modèle de vue .

Vous pouvez également consulter Windows Phone MVC qui possède également une navigation de type sécurisée. Vous pourriez même simplement être capable de tirer le code de navigation pour utiliser vous-même car il est sous licence sous licence sous MS-PL < / a>.

Autres conseils

En gros, non, ce n'est pas intégré.Les paramètres complexes tels que les instances IRepository dépassent malheureusement les capacités des fonctionnalités de navigation de Silverlight ;J'utilise généralement une forme de conteneur IoC pour les gérer.Les paramètres POCO plus simples sont facilement sérialisés en chaîne, mais cela nécessite toujours des chaînes magiques et une analyse manuelle des chaînes de requête.

Cependant, vous pouvez facilement créer vous-même quelque chose de type sécurisé.Par exemple, voici mon approche.

Pour les données de paramètres, j'ai une classe que j'appelle « Extras », qui enveloppe un Dictionary<string, object> avec des méthodes comme GetBool(string), GetInt32(string), etc., et a une méthode de fabrique statique CreateFromUri(Uri);c'est assez bon pour mes besoins.

Je l'utilise en conjonction avec une navigation de type sécurisé.J'aime beaucoup le modèle MVVM et chacune de mes pages possède un ViewModel encapsulant presque toute la logique.La relation un-à-un entre la page et ViewModel fait de ce dernier une clé de navigation idéale.Cela, combiné avec les attributs et la réflexion, nous donne une solution simple :

public class NavigationTargetAttribute : Attribute
{
    private readonly Type target;

    public ViewModelBase Target
    {
        get { return target; }
    }

    public NavigationTargetAttribute(Type target)
    {
        this.target = target;
    }
}

Mettez-en un sur chacune de vos pages, avec le type ViewModel approprié.

[NavigationTarget(typeof(LoginViewModel))]
public class LoginPage : PhoneApplicationPage
{ ... }

Ensuite, dans une classe singleton NavigationManager-esque, vous pouvez faire :

GetType().Assembly
    .GetTypes()
    .Select(t => new { Type = t, Attr = t.GetCustomAttributes(false).FirstOrDefault(attr => attr is NavigationTargetAttribute) })
    .Where(t => t.Attr != null);

Et juste comme ça, vous disposez d’une collection de tous les types navigables dans votre application.A partir de là, ce n'est plus beaucoup de travail pour les mettre dans un dictionnaire, par exemple.Si vous suivez une convention quant à l'endroit où vous placez vos pages, vous pouvez (par exemple) traduire assez facilement entre le type et l'Uri...Par exemple, new Uri("/Pages/" + myPageType.Name + ".xaml", UriKind.Relative).Ce n'est pas grand-chose de plus que d'ajouter la prise en charge des paramètres de requête.Finalement, vous obtiendrez une méthode comme celle-ci :

public void Navigate(Type target, Extras extras)
{
    Type pageType;
    if (navigationTargets.TryGetValue(target, out pageType))
    {
        var uri = CreateUri(pageType, extras);
        navigationService.NavigateTo(uri);
    }

    // error handling here
}

Enfin, dans la page OnNavigatedTo méthode, je fais quelque chose comme:

var extras = Extras.CreateFromUri(e.Uri);
((ViewModelBase) DataContext).OnNavigatedTo(extras);

Cela donne finalement un semblant de navigation fortement typée.Il s’agit d’une approche simple ;de mémoire, cela pourrait être amélioré en ajoutant les paramètres requis dans l'attribut de navigation et en les validant au moment de la navigation.Il ne prend pas non plus en charge les types de navigation plus complexes, dans lesquels la valeur des arguments de navigation déterminerait la destination finale.Néanmoins, cela convient à mon cas d'utilisation à 90 % - peut-être que cela fonctionnera pour vous aussi.

Il y a certainement certains détails omis ici, comme comment obtenir exactement une instance de NavigationService - Je pourrai préparer un échantillon plus complet plus tard ce soir, mais cela devrait suffire pour commencer.

Vous pouvez utiliser PhoneApplicationService.State

C'est un Dictionary<String,Object>

PhoneApplicationService.State est couramment utilisé dans le tombstoning pour stocker l'état actuel de l'application.Cependant, il peut être utilisé pour transmettre facilement des données entre les pages.

Documentation MSDN

Les applications Windows Phone sont désactivées lorsque l'utilisateur se rendra vers une autre application.Lorsque l'utilisateur revient à l'application, en utilisant le bouton Retour ou en remplissant une tâche de lanceur ou de sélecteur, l'application est réactivée.Une application peut stocker l'état d'application transitoire dans le dictionnaire d'État dans le gestionnaire de l'événement désactivé.Dans le gestionnaire d'événements activé, une application peut utiliser les valeurs stockées dans le dictionnaire d'état à l'état d'application transitoire.

En gros, ce que vous feriez est

PhoneApplicationService.State.add(selectedName,yourobjectInstance);
NavigationService.Navigate((new Uri("/MainPage.xaml?selectedItem="+selectedName,UriKind.Relative));

Ensuite, dans votre méthode de navigation, vous pouvez le récupérer

YourObject yourObjectInstance;
var yourObj = PhoneApplicationService.State["yourObjectName"];
yourObjectInstance = yourObj is YourObject ? (yourObj as YourObject) : null;

Voici un aperçu plus approfondi de la façon d'utiliser cette fonctionnalité

WPF prend en charge la navigation vers un objet déjà créé, mais WP8 n'en a pas Navigate surcharge.

Si vous ne souhaitez pas coder en dur les URI de page XAML, vous pouvez utiliser la fonction d'assistance suivante (un peu sale) pour obtenir l'URI de ressource .xaml d'une classe.

static Uri GetComponentUri<T>() where T : DependencyObject, new() {
    return BaseUriHelper.GetBaseUri(new T());
}

Ensuite, vous pouvez modifier cette URL et y accéder :

var baseUri = GetComponentUri<SomePage>(); //Uri="pack://application:,,,/MyProject;component/MainWindow.xaml"
var pageUri = new UriBuilder(baseUri) { Query = "selectedItem=" + bookName.Id };
NavigationService.Navigate(pageUri);

Notre solution qui fonctionne juste bien:
1. N'utilisez pas de chaînes de requête dans la page URIS, il s'agit simplement d'une nouvelle fois à nouveau MVVM, où la vue devrait simplement afficher des objets, mais la logique réelle pour le chargement et la sélection des éléments est dans la fenêtre de la vue.
2. Créez la classe avec les noms de page Const et quand vous souhaitez naviguer, utilisez simplement ceci:

public static class P
{
    public const string ArticlePage = "/Pages/ArticlePage.xaml";
    public const string OnlineSectionPage = "/Pages/OnlineSectionPage.xaml";
    public const string GalleryPage = "/Pages/GalleryPage.xaml";
    ...
}

// in our viewModel
NavigationService.Navigate(P.ArticlePage);

// In navigation service
public void Navigate(string pagePath)
{
    if (EnsureMainFrame())
    {
        mainFrame.Navigate(new Uri(pagePath, UriKind.RelativeOrAbsolute));
    }
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top