Windows phone 如何在windows phone 8中的页面之间传递非字符串参数?

Windows phone 如何在windows phone 8中的页面之间传递非字符串参数?,windows-phone,windows-phone-8,Windows Phone,Windows Phone 8,我正在将windows应用商店应用程序转换为windows phone 8。对于WinRT,可以在调用frame.navigate时将任何对象作为参数传递。(frame.navigate(类型sourcePageType,对象参数)) 对于windows phone,导航的工作方式似乎有所不同,您可以通过调用uri来导航,如:frame.navigate(新uri(“mypage.xaml”,UriKind.Relative)) windows文档指出,通过将字符串添加到uri,可以将其作为参数

我正在将windows应用商店应用程序转换为windows phone 8。对于WinRT,可以在调用frame.navigate时将任何对象作为参数传递。(frame.navigate(类型sourcePageType,对象参数))

对于windows phone,导航的工作方式似乎有所不同,您可以通过调用uri来导航,如:frame.navigate(新uri(“mypage.xaml”,UriKind.Relative))

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


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

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

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

首先,定义视图模型定位器。在app.xaml中的资源字典中创建此类的实例。将每个页面的DataContext设置为视图模型定位器的属性。有关示例,请参见

其次,使用GetAllItems()和GetItem(字符串id)等方法创建服务代理。在视图模型定位器中创建此服务代理的实例。将此引用传递到两个视图模型中


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

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

正如@gregstoll所述,Windows Phone中的最佳方法是发送一个标识符,然后利用App.ViewModel中的数据来访问所需的实际数据。查询字符串的长度是有限制的,在大多数情况下,您确实不想将其强调到极限


如果您能详细介绍一下您的项目场景,我们可以更好地帮助您确定最佳路径。

我最终扩展了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)var myParameter=NavigationService.GetLastNavigationData()
获取参数数据。

我只想添加上面Zik提供的伟大答案的VB.net版本。一旦我弄明白了如何将他的代码翻译成VB,我立刻让导航系统以类似WinRT/Windows8的方式工作

我使用以下代码创建了一个模块:

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
最后,要在我的另一个页面中,在OnNavigatedTo子页面中获取该对象:

ThisPageData = NavigationService.GetLastNavigationData()

Me.DataContext = ThisPageData

实际答案要归功于Zik。

MSDN概述了在页面之间传递非字符串参数的3种方法。这些包括:自定义导航扩展、静态属性和JSON+隔离存储。代码取自:

//
///自定义导航扩展。
///  
///  
///  
私有无效BTN方法1\u单击(对象发送方,路由目标)
{ 
NavigationService.Navigate(“/Result.xaml?name=1”,listString);
} 
///  
///静态特性
///  
///  
///  
私有无效BTN方法2\u单击(对象发送方,路由目标)
{ 
App.ObjectNavigationData=listString;
NavigationService.Navigate(新Uri(“/Result.xaml?name=2”,UriKind.Relative));
} 
///  
///Json+隔离存储
///  
///  
///  
私有无效BTN方法3_单击(对象发送方,路由目标)
{ 
字符串filePath=“objectData”;
使用(IsolatedStorageFile isolatedStorage=IsolatedStorageFile.GetUserStoreForApplication())
{ 
if(isolatedStorage.FileExists(filePath))
{ 
isolatedStorage.DeleteFile(文件路径);
} 
使用(IsolatedStorageFileStream fileStream=isolatedStorage.OpenFile(filePath,FileMode.Create,FileAccess.Write))
{ 
string writeDate=string.Empty;
//Json序列化。
使用(MemoryStream ms=new MemoryStream())
{ 
var ser=新数据契约JSONSerializer(类型(列表));
ser.WriteObject(ms,listString);
Seek女士(0,SeekOrigin.Begin);
var读取器=新的StreamReader(毫秒);
writeDate=reader.ReadToEnd();
} 
//保存到隔离存储。
使用(StreamWriter=newstreamwriter(fileStream))
{ 
WriteLine(writeDate);
} 
} 
} 
NavigationService.Navigate(新Uri(“/Result.xaml?name=3”,UriKind.Relative));
} 

如果您使用的是MVVM体系结构,则可以在使用Messenger注册后传递字符串或任何值。创建一个带有字符串(比如message)变量的模型类(比如PageMessage)。您希望将字符串从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;
 }
Messenger.Default.Register(此,(操作)=>ReceiveMessage(操作));
私有对象接收消息(页面消息操作)
{
字符串receivedMessage=action.message;
返回null;
}

您可以用一个名称保存在独立存储中,然后从另一个页面取回。这最好作为注释
Messenger.Default.Send(new PageMessage{message="Hello World"});
Messenger.Default.Register<PageMessage>(this, (action) => ReceiveMessage(action));

 private object ReceiveMessage(PageMessage action)
 {
    string receivedMessage=action.message;
    return null;
 }
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");
    }