2012-11-30 6 views
11

Ich arbeite daran, eine Windows Store App in Windows Phone 8 zu konvertieren. Für WinRT könnten Sie jedes Objekt als Parameter übergeben, wenn Sie frame.navigate aufrufen. (frame.navigate (typ sourcePageType, object parameter))Wie gebe ich Nicht-String-Parameter zwischen Seiten in Windows Phone 8?

Die Navigation scheint für Windows Phone anders zu funktionieren, Sie navigieren durch Aufruf in ein uri, wie zum Beispiel: frame.navigate (new uri ("mypage.xaml", UriKind .Relative))

Die Windows-Dokumentation merkt an, dass Sie eine Zeichenfolge als Parameter übergeben können, indem Sie sie zur uri hinzufügen.

Gibt es eine akzeptierte Möglichkeit, komplexe Objekte zwischen Seiten zu übergeben, die ich gerade nicht gefunden habe?

+2

können Sie im isolierten Speicher mit einem Namen speichern und dann nehmen Sie es von der anderen Seite zurück. –

+0

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

Antwort

0

In meinen Apps habe ich eine Art Bezeichner (Index, GUID, was auch immer) als Zeichenfolge übergeben und dann das Objekt in der OnNavigatedTo() - Methode der Seite gesucht, zu der Sie navigieren möchten. Die Objekte bleiben also im ViewModel (oder wo auch immer) und Sie können einfach einen String übergeben.

0

Ich würde empfehlen, einen Service-Agent zwischen zwei Ansichtsmodellen zu verwenden.

Definieren Sie zuerst einen Ansichtsmodell-Locator. Erstellen Sie eine Instanz dieser Klasse in einem Ressourcenwörterbuch in app.xaml. Setzen Sie den DataContext jeder Seite auf eine Eigenschaft des View Model Locators. Ein Beispiel finden Sie in John Papa's blog.

Zweitens, erstellen Sie einen Service-Agent mit Methoden wie GetAllItems() und GetItem (String-ID). Erstellen Sie eine Instanz dieses Service Agents im View Model Locator. Übergeben Sie diese Referenz in beide Ansichtsmodelle.

Drittens greifen Sie von der zweiten Ansicht aus auf das Ansichtsmodell zu, indem Sie den DataContext auf den Ansichtsmodelltyp umwandeln. Übergeben Sie den Navigationsparameter an das Ansichtsmodell, damit er GetItem aufrufen und seine Eigenschaften auffüllen kann.

0

Es ist nicht möglich, einen Navigationsparameter zu senden, der keine Zeichenfolge ist. Normalerweise verwende ich DataContractJsonSerializer, um die Daten zu serialisieren, die ich übertragen muss (aber hüte dich vor Uri-Längenbeschränkungen). Denken Sie auch daran, Uri.EscapeDataString (Parameter) zu verwenden, um die Zeichen in Ihrem querystring-Parameter zu umgehen.

0

Wie @ Gregstoll angegeben hat, ist die beste Methode in Windows Phone, eine Kennung zu senden und dann die Daten in Ihrem App.ViewModel zu verwenden, um auf die tatsächlichen Daten zuzugreifen, die Sie möchten. Es gibt Begrenzungen für die Länge des QueryStrings, und das möchten Sie in den meisten Fällen nicht so sehr betonen.

Wenn Sie ein wenig mehr über das Szenario Ihres Projekts erfahren können, können wir Ihnen besser helfen, den besten Weg zu finden.

+4

Dies wäre besser als Kommentar –

15

Ich landete die Navigation Klasse erweitern, etwa so:

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

Dann Sie NavigationService.Navigate("mypage.xaml", myParameter); auf der Quellseite und in der OnNavigatedTo Methode der Zielseite Aufruf var myParameter = NavigationService.GetLastNavigationData(); die Parameterdaten nennen würde zu bekommen.

3

Ich möchte nur eine VB.net-Version der großen Antwort von Zik oben zur Verfügung gestellt. Nachdem ich herausgefunden hatte, wie man seinen Code in VB übersetzt, hatte ich sofort eine Navigation ähnlich wie WinRT/Windows 8.

habe ich ein Modul mit dem folgenden Code:

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 

Und dann auf einem anderen Seite wie folgt navigieren:

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

Und schließlich, das Objekt in meiner anderen Seite zu bekommen, in dem OnNavigatedTo sub:

ThisPageData = NavigationService.GetLastNavigationData() 

Me.DataContext = ThisPageData 

Credit Zik für die tatsächliche Antwort.

0

In MSDN werden 3 Methoden zum Übergeben von Nicht-String-Parametern zwischen Seiten beschrieben. Dazu gehören: benutzerdefinierte Navigationserweiterungen, statische Eigenschaften und JSON + isolierter Speicher. Code aus Microsoft genommen:

/// <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

Wenn Sie MVVM Architektur verwenden, dann können Sie passieren Zeichenfolge oder einen beliebigen Wert nach der Verwendung von Messenger Registrierung. Erstellen Sie eine Modellklasse (z. B. PageMessage) mit einer String-Variable (z. B. Nachricht). Sie wollen Zeichenfolge von homepage.xaml passieren newpage.xaml, dann in homepage.xaml nur die Nachricht senden wie diese

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

Im newpage.xaml, sollten Sie die Boten wie dieses Register,

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