在WP7 Silverlight应用程序中导航时将复杂对象传递给页面

And*_*ech 15 c# navigation silverlight windows-phone-7

我一直在使用NavigationServiceNavigate方法导航到我的WP7的Silverlight应用程序的其他页面:

NavigationService.Navigate(new Uri("/Somepage.xaml?val=dreas", UriKind.Relative));
Run Code Online (Sandbox Code Playgroud)

Somepage.xaml,我然后检索查询字符串参数,如下所示:

string val;
NavigationContext.QueryString.TryGetValue("val", out val);
Run Code Online (Sandbox Code Playgroud)

我现在需要一种使用类似方式传递复杂对象的方法.每次我需要将对象传递给新页面时,如何在不必序列化对象的情况下执行此操作?

Jus*_*gel 14

这是一个非常复杂的问题,这里没有简单的解决方案.没有神奇的API可以用于任何应用程序来解决这个问题.

传递导航数据的核心问题是墓碑.默认情况下逻辑删除的唯一数据是导航URI.因此,如果您使用的是QueryString参数,它将通过逻辑删除和您的代码自动获取.只要您手动传递对象的实例,就必须自己手动为该实例进行逻辑删除.

因此,如果您导航到"/CowDetails.xaml?ID=1",您的页面可能只需要通过ID查询字符串参数就可以获得完美的逻辑删除.但是,如果你以某种方式为CowDetails页面提供了一个"new Cow(){ID = 1}",那么你必须自己确保墓碑和zombificate这个值.

此外,还有时间问题.在调用NavigationService.Navigate时,您正在导航的页面也没有实际的实例.因此,即使您正在导航到FooPage并准备好FooData,也无法立即将FooPage连接到FooData.您必须等到PhoneApplicationFrame.Navigated事件被触发才能为FooPage提供FooData.

我通常处理这个问题的方法是:

  1. 具有对象类型数据属性的BasePage
  2. 让NavigationHelper获取页面URI和数据:NavigationHelper.Navigate("foo.xaml",fooData)
  3. 让NavigationHelper注册到PhoneApplicationFrame.Navigated事件,如果它是"foo.xaml",则将BasePage.Data设置为FooData.
  4. 让BasePage使用JSON.Net到tombstone和zombificate BasePage.Data.
  5. 在BasePage上,我有一个OnDataSet虚拟方法,一旦通过Zombification或Navigation填充Data属性就会调用它.在这种方法中,所有与业务数据有关的事情都会发生.


Luk*_*don 9

App.xaml.cs - > App类,在那里添加一个字段/属性.要访问它,如果是静态使用:

App.MyComplexObject
Run Code Online (Sandbox Code Playgroud)

或者如果不是staic

(App.Current as App).MyComplexObject;
Run Code Online (Sandbox Code Playgroud)


vjs*_*ath 5

解决这个问题有一个非常简单的解决方案.请考虑以下示例Windows Phone应用程序有以下两个页面,Page1.xamlPage2.xaml 让我们从Page1.xaml说我们正在导航到Page2.xaml.当您调用NavigationService.Navigate方法时,导航循环开始

  1. 第一次OnNavigatingFrom Page1事件发生
  2. 然后构造函数第2页火灾
  3. 然后OnNavigatedFrom Page1的事件触发其EventArgs中创建的页面的引用(e.Content具有创建的Page2实例)
  4. 最后OnNavigatedTo Page2事件发生了

因此,我们在导航开始的页面中获取其他页面的引用.

public class PhoneApplicationBasePage : PhoneApplicationPage
{

private object navParam = null;
protected object Parameter{get;private set;}
//use this function to start the navigation and send the object that you want to pass 
//to the next page
protected void Navigate(string url, object paramter = null)
 {    
   navParam = paramter;
   this.NavigationService.Navigate(new Uri(url, UriKind.Relative));
 }

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
//e.Content has the reference of the next created page
if (e.Content is PhoneApplicationBasePage )
  {
   PhoneApplicationBasePage  page = e.Content as PhoneApplicationBasePage;
   if (page != null)
   { page.SendParameter(navParam); navParam=null;}
  }
}
private void SendParameter(object param)
{
 if (this.Parameter == null)
  {
   this.Parameter = param;
   this.OnParameterReceived();
  }
}
protected virtual void OnParameterReceived()
{
//Override this method in you page. and access the **Parameter** property that
// has the object sent from previous page
}
}
Run Code Online (Sandbox Code Playgroud)

所以在我们的Page1.xaml.cs中,我们只需要调用Navigate("/Page2.xaml",myComplexObject).在你的Page2.xaml.cs中,我们将覆盖OnParameterReceived方法

 protected override void OnParameterReceived()
{
var myComplexObjext = this.Parameter;
}
Run Code Online (Sandbox Code Playgroud)

而且,通过PhoneApplicationBasePage中的更多调整,也可以处理墓碑问题