2012-11-30 13 views
11

Sto lavorando alla conversione di un'app di Windows Store in Windows Phone 8. Per WinRT, è possibile passare qualsiasi oggetto come parametro quando si chiama frame.navigate. (frame.navigate (tipo sourcePageType, parametro oggetto))Come passare i parametri non stringa tra le pagine di Windows Phone 8?

La navigazione sembra funzionare in modo diverso per Windows Phone, si naviga chiamando in un uri, come: frame.navigate (nuovo uri ("mypage.xaml", UriKind .Relativo))

La documentazione di Windows indica che è possibile passare una stringa come parametro aggiungendola all'ur.

Esiste un modo accettato di passare oggetti complessi tra le pagine che non ho trovato?

+2

è possibile salvare nell'archivio isolato con un nome e quindi riprenderlo dall'altra pagina. –

+0

http://stackoverflow.com/questions/12444816/how-to-pass-values-parameters-between-xaml-pages/12444817#12444817 –

risposta

0

Quello che ho fatto nelle mie app è passare una sorta di identificatore (indice, GUID, qualunque cosa) come stringa, e quindi cercare l'oggetto nel metodo OnNavigatedTo() della pagina a cui vuoi navigare. Quindi gli oggetti rimarranno memorizzati nel ViewModel (o dovunque) e potrai semplicemente passare una stringa.

0

Si consiglia di utilizzare un agente di servizio tra due modelli di visualizzazione.

Innanzitutto, definire un indicatore di posizione del modello di vista. Creare un'istanza di questa classe in un dizionario delle risorse in app.xaml. Imposta il DataContext di ogni pagina su una proprietà del localizzatore del modello di vista. Vedere John Papa's blog per un esempio.

In secondo luogo, creare un agente di servizio con metodi come GetAllItems() e GetItem (id stringa). Creare un'istanza di questo agente di servizio nel localizzatore del modello di vista. Passa questo riferimento in entrambi i modelli di vista.

In terzo luogo, accedere al modello di vista dalla seconda vista eseguendo il cast di DataContext sul tipo di modello di visualizzazione. Passa il parametro di navigazione al modello di vista in modo che possa chiamare GetItem e popolare le sue proprietà.

0

Non esiste alcun modo per inviare un parametro di navigazione che non sia una stringa. Di solito uso DataContractJsonSerializer per serializzare i dati che devo trasferire (ma attenzione ai limiti di lunghezza di Uri). Ricordarsi inoltre di utilizzare Uri.EscapeDataString (parametro) per uscire dai caratteri nel parametro querystring.

0

Come indicato da @gregstoll, la metodologia migliore in Windows Phone è inviare un identificatore e quindi utilizzare i dati nell'app.ViewModel per accedere ai dati effettivi desiderati. Ci sono limitazioni sulla lunghezza di QueryString e, per la maggior parte, non vuoi sottolineare questo ai suoi limiti.

Se puoi dire qualcosa di più sullo scenario del tuo progetto, potremmo aiutarti meglio a determinare il percorso migliore da intraprendere.

+4

Questo sarebbe meglio come commento –

15

ho finito per estendere la classe NavigationService, in questo modo:

public static class NavigationExtensions 
{ 
    private static object _navigationData = null; 

    public static void Navigate(this NavigationService service, string page, object data) 
    { 
     _navigationData = data; 
     service.Navigate(new Uri(page, UriKind.Relative)); 
    } 

    public static object GetLastNavigationData(this NavigationService service) 
    { 
     object data = _navigationData; 
     _navigationData = null; 
     return data; 
    } 
} 

Poi si chiamerebbe NavigationService.Navigate("mypage.xaml", myParameter); sulla pagina di origine, e nel metodo OnNavigatedTo della pagina di destinazione chiamata var myParameter = NavigationService.GetLastNavigationData(); per ottenere i dati dei parametri.

3

Voglio solo aggiungere una versione VB.net della grande risposta fornita da Zik sopra. Una volta capito come tradurre il suo codice in VB ho avuto immediatamente navigazione in modo simile a WinRT/Windows 8.

ho creato un modulo con il seguente codice:

Module NavigationExtensionsModule 

Sub New() 
End Sub 
Private _navigationData As Object = Nothing 

<System.Runtime.CompilerServices.Extension> _ 
Public Sub Navigate(service As NavigationService, page As String, data As Object) 
    _navigationData = data 
    service.Navigate(New Uri(page, UriKind.Relative)) 
End Sub 

<System.Runtime.CompilerServices.Extension> _ 
Public Function GetLastNavigationData(service As NavigationService) As Object 
    Dim data As Object = _navigationData 
    _navigationData = Nothing 
    Return data 
End Function 
End Module 

E poi passare a un'altra pagina come questa:

NavigationService.Navigate("pagename.xaml", ObjectToPassToThePage) 

E, infine, per ottenere tale oggetto nella mia altra pagina, nella OnNavigatedTo sub:

ThisPageData = NavigationService.GetLastNavigationData() 

Me.DataContext = ThisPageData 

Credito a Zik per la risposta effettiva.

0

MSDN delinea 3 metodi per passare parametri non stringa tra le pagine. Questi includono: estensioni di navigazione personalizzate, proprietà statiche e archiviazione isolata JSON +. Codice tratto da Microsoft:

/// <summary> 
    /// Custom Navigation Extensions. 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void btnMethod1_Click(object sender, RoutedEventArgs e) 
    { 
     NavigationService.Navigate("/Result.xaml?name=1", listString); 
    } 


    /// <summary> 
    /// Static properties 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void btnMethod2_Click(object sender, RoutedEventArgs e) 
    { 
     App.ObjectNavigationData = listString; 
     NavigationService.Navigate(new Uri("/Result.xaml?name=2", UriKind.Relative)); 
    } 


    /// <summary> 
    /// Json + IsolatedStorage 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void btnMethod3_Click(object sender, RoutedEventArgs e) 
    { 
     string filePath = "objectData"; 


     using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication()) 
     { 
      if (isolatedStorage.FileExists(filePath)) 
      { 
       isolatedStorage.DeleteFile(filePath); 
      } 


      using (IsolatedStorageFileStream fileStream = isolatedStorage.OpenFile(filePath, FileMode.Create, FileAccess.Write)) 
      { 
       string writeDate = string.Empty; 


       // Json serialization. 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        var ser = new DataContractJsonSerializer(typeof(List<string>)); 
        ser.WriteObject(ms, listString); 
        ms.Seek(0, SeekOrigin.Begin); 
        var reader = new StreamReader(ms); 
        writeDate = reader.ReadToEnd(); 
       } 


       // Save to IsolatedStorage. 
       using (StreamWriter writer = new StreamWriter(fileStream)) 
       { 
        writer.WriteLine(writeDate); 
       } 
      } 
     } 


     NavigationService.Navigate(new Uri("/Result.xaml?name=3", UriKind.Relative)); 
    } 
2

Se si utilizza l'architettura MVVM, allora si può passare stringa o qualsiasi valore dopo la registrazione usando Messenger. Creare una classe modello (ad esempio PageMessage) con una variabile stringa (ad esempio messaggio). Si vuole passare stringa dal homepage.xaml a newpage.xaml, poi nel homepage.xaml basta inviare il messaggio come questo

Messenger.Default.Send(new PageMessage{message="Hello World"}); 

Nel newpage.xaml, è necessario registrarsi al messaggero in questo modo,

Messenger.Default.Register<PageMessage>(this, (action) => ReceiveMessage(action)); 

private object ReceiveMessage(PageMessage action) 
{ 
    string receivedMessage=action.message; 
    return null; 
} 
0
Yes there is a way to use a complex object in different pages in wp8 or wp7. You can use complex objects between pages by IsolatedStorageSettings. 

IsolatedStorageSettings AppSettings = IsolatedStorageSettings.ApplicationSettings; 

// to save an object in isolatedstoragesettings 
if (!AppSettings.Contains("ObjectKey")) 
     AppSettings.Add("ObjectKey", Your object value); 
else 
     AppSettings["ObjectKey"] = Your object value; 

// to retrieve value of an object from isolatedstoragesettings 
if(AppSettings.Contains("ObjectKey")) 
    { 
    var objectValue = (Cast object to type)AppSettings["ObjectKey"]; 
    //Remove 
    AppSettings.Remove("ObjectKey"); 
    }