Domanda

Sto cercando un modo per navigare tra le schermate nella mia app.Fondamentalmente quello che ho visto finora consiste nel passare un URI di stringa al NavigationService, completo di parametri di stringa di query., E.G.

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

Non sono davvero appassionato di questo anche se alla fine perché richiede stringhe magiche, e possono portare a problemi lungo la strada.

Idealmente creerei solo un'istanza della classe che voglio navigare, passando i parametri come argomenti per il costruttore.È possibile?Se è così, come?

È stato utile?

Soluzione

Mentre la navigazione effettiva dovrà utilizzare le stringhe alla fine, è possibile creare o utilizzare un wrapper che è tipo sicuro.

Suggerirei di guardare a caliburn micro anche se lo usassi solo per la navigazione sicura del tipo. Ecco uno snippet Da un tutorial sull'utilizzo di WP8 :

.

Il navigationservice fornito con il toolkit supporta un modello di visualizzazione Primo approccio : invece di dichiarare quale è l'URL della pagina in cui vogliamo prendere l'utente (questo è l'approccio standard), noi Dichiara quale è il ViewModel che vogliamo visualizzare. Il servizio si prenderà cura di creare l'URL corretto e visualizzare la vista che è associata al modello di visualizzazione .

In alternativa è possibile guardare a Windows Phone MVC che ha anche qualche tipo di navigazione sicura. Potresti persino essere in grado di tirare fuori il codice di navigazione da usare da solo da quando è concesso in licenza in licenza in ms-pl < / a>.

Altri suggerimenti

Fondamentalmente, no, non è integrato. I parametri complessi come le istanze Irepository sono, purtroppo, oltre la capacità delle strutture di navigazione in Silverlight; Di solito uso qualche forma di contenitore IOC per gestire quelli. I parametri POCO più semplici sono facilmente serializzati a una stringa, ma che richiede ancora stringhe magiche e parsing della corda di query manuale.

Puoi, tuttavia, costruire facilmente qualcosa di te stesso. Ad esempio, ecco il mio approccio.

Per i dati dei parametri, ho una classe che chiamo 'Extras', che avvolge un Dictionary<string, object> con metodi come GetBool(string), GetInt32(string), ecc. e ha un metodo di fabbrica statico CreateFromUri(Uri); Questo è abbastanza buono per i miei scopi.

Lo uso in combinazione con la navigazione sicura di tipo. Mi piace molto il modello MVVM, e ognuna delle mie pagine ha un mirino che incapsulando quasi tutta la logica. La relazione one-to-one della pagina a ViewModel rende quest'ultima una chiave di navigazione ideale. Quello, combinato con attributi e riflessione, ci dà una soluzione semplice:

public class NavigationTargetAttribute : Attribute
{
    private readonly Type target;

    public ViewModelBase Target
    {
        get { return target; }
    }

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

Metti uno di questi su ciascuna delle tue pagine, con il tipo di vista corretto.

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

Allora, in una classe di navigazione di singletonManager-Esque, puoi fare:

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

E proprio così, hai una raccolta di ogni tipo navigabile nella tua app. Da lì, non è molto più lavoro per metterli in un dizionario, per esempio. Se segui una convenzione per dove metti le tue pagine, puoi (ad esempio) Traduci tra tipo e URI abbastanza facilmente ... ad esempio, new Uri("/Pages/" + myPageType.Name + ".xaml", UriKind.Relative). Non è molto altro per aggiungere supporto per i parametri della query. Infine, finirai con un metodo, come così:

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
}
.

Infine, nel metodo OnNavigatedTo Page, faccio qualcosa come:

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

Questo, infine, dà una parvenza di una navigazione fortemente digitata. Questo è un approccio nudo delle ossa; Fuori dalla parte superiore della testa, questo potrebbe essere migliorato aggiungendo parametri richiesti nell'attributo di navigazione e convalidarli a tempo di navigazione. Inoltre non supporta tipi di navigazione più complessi, in cui il valore degli argomenti del nav determinerebbe la destinazione finale. Tuttavia, questo si adatta al mio caso di uso del 90% - forse funzionerà anche per te.

Ci sono sicuramente alcuni dettagli omessi qui, come esattamente come ottenere esattamente un'istanza di NavigationService - posso lavorare su un campione più completo più tardi stasera, ma questo dovrebbe essere sufficiente per iniziare.

È possibile utilizzare PhoneApplicationService.State

è un Dictionary<String,Object>

PhoneApplicationService.State viene comunemente utilizzato nella topponia per memorizzare lo stato corrente dell'applicazione. Tuttavia, può essere utilizzato per passare convenientemente i dati tra le pagine.

Documentazione MSDN

.

Le applicazioni Windows Phone sono disattivate quando l'utente naviga un'altra applicazione. Quando l'utente ritorna all'applicazione, da Utilizzo del pulsante Indietro o completando un avvio di launcher o Shouser, il L'applicazione è riattivata. Un'applicazione può memorizzare transitori Stato dell'applicazione nel dizionario statale nel gestore per il Evento disattivato. Nel gestore di eventi attivato, un'applicazione può Utilizzare i valori memorizzati nel dizionario State in applicazione transitoria stato.

Fondamentalmente quello che faresti è

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

Poi nel tuo metodo navigato è possibile recuperarlo

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

Ecco un aspetto più approfondito su come utilizzare questa funzione

WPF supporta la navigazione su un oggetto già creato, ma il WP8 manca che sovraccarichi di generazione di Navigate.

Se non si desidera il codice hard-code a Xaml Uris, è possibile utilizzare la seguente funzione di helper (un po 'sporca) per ottenere l'URI di risorse .xaml di qualche classe.

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

Quindi puoi modificare quell'URL e accedere ad esso:

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

La nostra soluzione che funziona bene:
1. Non utilizzare le stringhe di query In Uris della pagina, questo è solo completamente di nuovo MVVM dove la vista dovrebbe semplicemente visualizzare roba, ma la logica effettiva per il caricamento e la selezione degli elementi è in ViewModel.
2. Creare la classe con i nomi delle pagine cost e ogni volta che si desidera navigare, basta usare questo:

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));
    }
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top