如何在Windows Phone 8中传递非字符串参数?

11

我正在将Windows Store应用转换为Windows Phone 8。对于WinRT,当调用frame.navigate时,您可以将任何对象作为参数传递。(frame.navigate(type sourcePageType, object parameter))

在Windows Phone上,导航似乎有所不同,您需要通过调用uri来导航,例如:frame.navigate(new uri("mypage.xaml", UriKind.Relative))

Windows文档指出,您可以通过将字符串添加到uri中来将其作为参数传递。

是否有一种接受的方式可以在页面之间传递复杂对象,而我只是没有找到?


2
你可以将数据保存在独立存储中,并指定一个名称,然后从其他页面检索它。 - luis_laurent
https://dev59.com/b2cs5IYBdhLWcg3w-YlD#12444817 - Daniel Little
9个回答

15

我最终扩展了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(); 方法以获取参数数据。


3

我希望能够提供一份VB.net版本的优秀答案翻译,Zik已经提供了很好的答案。一旦我弄清楚了如何将他的代码转换为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子程序中获取另一页中的对象:

ThisPageData = NavigationService.GetLastNavigationData()

Me.DataContext = ThisPageData

感谢 Zik 提供实际答案。

2
如果您正在使用MVVM架构,则可以在注册Messenger后传递字符串或任何值。创建一个模型类(比如PageMessage),其中包含一个字符串变量(比如message)。如果您想从homepage.xaml传递字符串到newpage.xaml,则只需在homepage.xaml中像这样发送消息即可。
Messenger.Default.Send(new PageMessage{message="Hello World"});

在newpage.xaml中,您应该像这样注册messenger:
Messenger.Default.Register<PageMessage>(this, (action) => ReceiveMessage(action));

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

0

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

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

0
在我的应用程序中,我所做的是将某种标识符(索引、GUID或其他)作为字符串传递,然后在要导航到的页面的OnNavigatedTo()方法中查找对象。因此,对象将保留在ViewModel(或其他位置),您只需传递一个字符串即可。

0

我建议在两个视图模型之间使用服务代理。

首先,定义一个视图模型定位器。在app.xaml的资源字典中创建此类的实例。将每个页面的DataContext设置为视图模型定位器的属性之一。请参见John Papa's blog以获取示例。

其次,创建一个服务代理,其中包含像GetAllItems()和GetItem(string id)这样的方法。在视图模型定位器中创建此服务代理的实例。将此引用传递到两个视图模型中。

第三,通过将DataContext强制转换为视图模型类型来从第二个视图访问视图模型。将导航参数传递给视图模型,以便它可以调用GetItem并填充其属性。


0

无法发送非字符串的导航参数。我通常使用DataContractJsonSerializer来序列化需要传输的数据(但要注意Uri长度限制)。 还要记得使用Uri.EscapeDataString(parameter)来转义查询字符串参数中的字符。


0
正如@gregstoll所说,在Windows Phone中最好的方法是发送一个标识符,然后利用App.ViewModel中的数据访问实际想要的数据。 QueryString的长度有限制,大多数情况下,您真的不希望将其压力到极限。
如果您能多说一点关于您项目的场景,我们可以更好地帮助您确定最佳路径。

4
这更适合作为评论。 - James A Mohler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接