Подтвердить что ты не робот

Как передать нестрочные параметры между страницами в Windows Phone 8?

Я работаю над преобразованием приложения магазина Windows в Windows Phone 8. Для WinRT вы можете передать любой объект в качестве параметра при вызове frame.navigate. (frame.navigate(type sourcePageType, параметр объекта))

Навигация по-разному работают для телефона Windows, вы перемещаетесь, вызывая в uri, например: frame.navigate(новый uri ( "mypage.xaml", UriKind.Relative))

В документации к окну указано, что вы можете передать строку в качестве параметра, добавив ее в uri.

Есть ли приемлемый способ передачи сложных объектов между страницами, которые я просто не нашел?

4b9b3361

Ответ 1

Я закончил расширение класса NavigationService, например:

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

Затем вы вызываете NavigationService.Navigate("mypage.xaml", myParameter); на исходной странице и в методе OnNavigatedTo вызова целевой страницы var myParameter = NavigationService.GetLastNavigationData();, чтобы получить данные параметров.

Ответ 2

Я хочу просто добавить версию VB.net отличного ответа, представленного Зиком выше. Как только я понял, как перевести свой код на VB, я сразу же применил навигацию, аналогичную способу WinRT/Windows 8.

Я создал модуль со следующим кодом:

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

Затем перейдите к другой странице, например:

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

И наконец, чтобы получить этот объект на моей другой странице, в OnNavigatedTo sub:

ThisPageData = NavigationService.GetLastNavigationData()

Me.DataContext = ThisPageData

Кредит Zik за фактический ответ.

Ответ 3

Если вы используете MVVM-архитектуру, вы можете передать строку или любое значение после регистрации с помощью Messenger. Создайте класс модели (например, PageMessage) со строкой (например, с сообщением). Вы хотите передать строку с homepage.xaml на newpage.xaml, а затем на homepage.xaml просто отправьте сообщение, подобное этому

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

В newpage.xaml вы должны зарегистрировать мессенджер, как это,

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

 private object ReceiveMessage(PageMessage action)
 {
    string receivedMessage=action.message;
    return null;
 }

Ответ 4

То, что я сделал в своих приложениях, это передать какой-то идентификатор (индекс, GUID, как угодно) в виде строки, а затем искать объект в методе OnNavigatedTo() страницы, к которой вы хотите перейти. Таким образом, объекты будут храниться в ViewModel (или везде), и вы можете просто передать строку.

Ответ 5

Я бы рекомендовал использовать агент обслуживания между двумя моделями просмотров.

Сначала определите локатор модели представления. Создайте экземпляр этого класса в словаре ресурсов в app.xaml. Установите DataContext каждой страницы в свойство локатора модели представления. См. блог Джона Папы для примера.

Во-вторых, создайте агент службы с помощью методов GetAllItems() и GetItem (идентификатор строки). Создайте экземпляр этого агента обслуживания в локаторе модели представления. Передайте эту ссылку в обе модели просмотра.

В-третьих, получить доступ к модели представления из второго представления, отбросив DataContext до типа модели представления. Передайте параметр навигации в модель представления, чтобы он мог вызвать GetItem и заполнить его свойства.

Ответ 6

Невозможно отправить параметр навигации, который не является строкой. Я обычно использую DataContractJsonSerializer для сериализации данных, которые мне нужно передать (но остерегайтесь ограничений длины Uri). Также не забудьте использовать Uri.EscapeDataString(параметр), чтобы избежать символов в вашем параметре querystring.

Ответ 7

Как указано в @gregstoll, лучшей методологией в Windows Phone является отправка идентификатора, а затем использование данных в вашем App.ViewModel для доступа к фактическим данным, которые вы хотите. Существуют ограничения по длине QueryString и по большей части, вы действительно не хотите подчеркивать, что это ограничивает.

Если вы можете немного рассказать о своем сценарии проекта, мы могли бы лучше помочь вам в определении наилучшего пути.

Ответ 8

MSDN выделяет 3 метода для передачи нестроковых параметров между страницами. К ним относятся: пользовательские расширения навигации, статические свойства и изолированное хранилище JSON+. Код, взятый из 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)); 
   } 

Ответ 9

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