C# 在WP7 Silverlight应用程序中导航时向页面传递复杂对象
我一直在使用C# 在WP7 Silverlight应用程序中导航时向页面传递复杂对象,c#,silverlight,windows-phone-7,navigation,C#,Silverlight,Windows Phone 7,Navigation,我一直在使用NavigationService的Navigate方法导航到我的WP7 Silverlight应用程序中的其他页面: NavigationService.Navigate(new Uri("/Somepage.xaml?val=dreas", UriKind.Relative)); 然后,我从Somepage.xaml检索查询字符串参数,如下所示: string val; NavigationContext.QueryString.TryGetValue("val", out v
NavigationService
的Navigate
方法导航到我的WP7 Silverlight应用程序中的其他页面:
NavigationService.Navigate(new Uri("/Somepage.xaml?val=dreas", UriKind.Relative));
然后,我从Somepage.xaml
检索查询字符串参数,如下所示:
string val;
NavigationContext.QueryString.TryGetValue("val", out val);
我现在需要一种使用类似方式传递复杂对象的方法。如果每次需要将对象传递到新页面时都不必序列化对象,如何执行此操作?App.xaml.cs->App class,在那里添加字段/属性。要访问它,如果它是静态的,请使用:
App.MyComplexObject
如果不是staic
(App.Current as App).MyComplexObject;
这是一个极其复杂的问题,这里没有简单的解决方案。没有一个神奇的API可以为任何应用程序解决这个问题 传递导航数据的核心问题是墓碑问题。默认情况下唯一被删除的数据块是导航URI。因此,如果您使用的是QueryString参数,它将通过逻辑删除和代码自动获取。但是,无论何时手动传递对象的实例,都必须自己手动为该实例进行逻辑删除 因此,如果导航到“/CowDetails.xaml?ID=1”,只需选择ID Querystring参数,您的页面就可能具有完美的墓碑。但是,如果您以某种方式为CowDetails页面提供了一个“new Cow(){ID=1}”,那么您必须确保自己将该值墓碑化和僵尸化 还有时间问题。调用NavigationService.Navigate时,您正在导航的页面还没有实际的实例。因此,即使您正在导航到FooPage并准备好FooData,也无法立即将FooPage连接到FooData。您必须等待PhoneApplicationFrame.Navigated事件触发后,才能向FooPage提供FooData 我通常处理这个问题的方式是:
有争议的解决方案,如果有的话,让它成为暂时的 在应用程序的命名空间下为任何需要的页面创建该名称
public static class VarsForPages {
// Be sure to include public static.
public static SomeClass SomeClassObject;
public static List<string> SomeList = new List<string>();
public static string SomeData = "SomeValue";
}
// The syntax for referencing the data
VarsForPages.SomeClassObject;
VarsForPages.SomeList;
VarsForPages.SomeData;
公共静态类varsforpage{
//确保包含公共静态文件。
公共静态SomeClass SomeClassObject;
public static List SomeList=new List();
公共静态字符串SomeData=“SomeValue”;
}
//用于引用数据的语法
VarsForPages.SomeClassObject;
VarsForPages.SomeList;
VarsForPages.SomeData;
现在,您可以在应用程序中的任何位置引用SomeClassObject、SomeList和SomeData
注意:与任何全局数据一样,对可能对全局数据进行的许多访问和修改感到厌倦。我之所以这样说,是因为我曾经有一个列表的大小增加了,但是我在应用程序中的一个页面依赖于列表的大小,这导致了一个bug。别忘了,数据是全球性的 解决这个问题有一个非常简单的方法。考虑下面的例子 windows phone应用程序有以下两个页面,Page1.xaml和Page2.xaml 假设我们从Page1.xaml导航到Page2.xaml。当您调用NavigationService.Navigate方法时,导航周期开始
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
}
}
因此,在我们的Page1.xaml.cs中,我们只需调用导航(“/Page2.xaml”,myComplexObject)
。在您的Page2.xaml.cs中,我们将覆盖OnParameterReceived方法
protected override void OnParameterReceived()
{
var myComplexObjext = this.Parameter;
}
而且,在PhoneApplicationBasePage中稍加调整也可以处理墓碑问题,我希望我能回复上面vjsrinath的回复;这是最好的方法。非常感谢 这可能是我见过的最接近iOS模型工作原理的东西,从第一页开始,您称之为performsgue(=NavigateTo)。然后您会得到一个名为prepareforsgue的回调,它允许您在目标页面中设置变量,设置委托(通常为self),诸如此类 对于复杂的对象传递,它可以轻松地传递URL中的参数 作为一个明确的示例,假设我想将我的应用程序的版本字符串传递到单独项目中的“关于”框中: 在调用类中:
private void About_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/Library;component/Pages/About.xaml", UriKind.Relative));
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (e.Content is About)
{
About page = e.Content as About;
if (page != null)
{
page.VersionString = App.VersionText;
}
}
base.OnNavigatedFrom(e);
}
在About类中:
public partial class About : PhoneApplicationPage
{
public string VersionString { get; set; }
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
versionTextBlock.Text = VersionString;
}
}
当然,这是一个非常简单的示例,但是您要传递的属性可以是任何对象,这使得它非常强大。当然,它可以包括诸如“saveButtonPressed”等回调,因此保存处理可以在调用类中完成,而不是在呈现的视图中完成,这对于代码整洁来说是非常糟糕的。e、 g
page.OnSaveButtonPressed = this.SaveButtonPressedHandler; // Pass object to save as parameter
是不是你不想做序列化,但不介意推卸责任?如果是这样的话,我听说IsolatedStorage
已经得到了改进-可以吗