【问题标题】:How do I pass non-string parameters between pages in windows phone 8?如何在 windows phone 8 中的页面之间传递非字符串参数?
【发布时间】:2012-11-30 22:57:05
【问题描述】:

我正在将 Windows 商店应用程序转换为 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 来将其作为参数传递。

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

【问题讨论】:

标签: windows-phone windows-phone-8


【解决方案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】:

    我只想添加上面 Zik 提供的最佳答案的 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 子页面中获取该对象:

    ThisPageData = NavigationService.GetLastNavigationData()
    
    Me.DataContext = ThisPageData
    

    感谢 Zik 的实际答案。

    【讨论】:

      【解决方案3】:

      如果您使用的是 MVVM 架构,那么您可以在使用 Messenger 注册后传递字符串或任何值。创建一个带有字符串(比如消息)变量的模型类(比如 PageMes​​sage)。您想将字符串从 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;
       }
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案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");
                    } 
                

                【讨论】:

                  猜你喜欢
                  • 2013-12-12
                  • 1970-01-01
                  • 2016-07-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-09-16
                  相关资源
                  最近更新 更多