我正在寻找有关如何将数据从一个页面传递到另一个页面的最佳实践。
在页面A中,我有一个按钮,可以触发页面B. 在页面B上,我有6个文本框,允许用户输入信息。 用户完成后,单击按钮将其返回到页面A.
我想将该数据传回页面A.
我见过以下建议:
我正在寻找最佳实践。是否有微软推荐的或者通常被认为是最好的方式?
由于
答案 0 :(得分:63)
PhoneApplicationService.Current.State["yourparam"] = param
NavigationService.Navigate(new Uri("/view/Page.xaml", UriKind.Relative));
然后在其他页面中
var k = PhoneApplicationService.Current.State["yourparam"];
答案 1 :(得分:23)
我个人将在页面B上输入的值存储在A页也可以访问的模型(对象)中。
根据您第二次导航到Page A的方式,以下一项或多项内容可能有助于了解页面之间的传递值:
How to pass the image value in one xaml page to another xaml page in windows phone 7?
Passing a complex object to a page while navigating in a WP7 Silverlight application
How to pass an object from a xaml page to another?
How to pass a value between Silverlight pages for WP7?
How do I navigate from one xaml page to another, and pass values?
答案 2 :(得分:4)
您可以考虑使用MVC:让您的App成为控制器,将所有数据存储在模型中,页面只是包含纯UI逻辑的视图。在这种情况下,您的页面是画家,并且您传递模型对象。这样可以很好地隔离业务逻辑和UI,以便您可以轻松地对其进行修改。
BTW,Silverlight和XAML是MVC的绝佳工具,因此它是一种天生的匹配。答案 3 :(得分:3)
这里有几件事情在发挥作用。首先,如果/当用户使用“后退”按钮返回页面A而不是按钮时,是否交换了文本框中的信息(返回=取消,还是返回=确定?)
那就是说,如果你使用的是NavigationService.GoBack(你应该使用NavigationService.Navigate,因为如果你使用Navigate调用,反复点击后退键会导致你的用户遇到各种各样的不良用户体验) ,那么QueryStrings不是一个选项。由于页面实际上无法在WP7 Silverlight导航系统中相互引用,因此您需要使用第三方来保存数据。为此,您可以转向(a)隔离存储(慢速和重度,但是故障安全),(b)使用PhoneApplicationService.State字典,或(c)使用某种类型的全局属性,或者挂起应用程序对象,或使用Statics / Singletons ......
当你这样做时,请记住要观察Tombstoning行为 - 当您(a)在应用程序中导航到它时,您的页面将处理OnNavigatedTo方法(b)当您完成页面B上的工作时导航回到它,或者(c)您从该页面标记您的应用程序并使用返回键返回到您的应用程序。
抱歉,我没有给出更直接的答案 - 很大程度上取决于您的具体情况。在最一般的情况下,我强烈考虑在PhoneApplicationService上使用应用程序状态字典...它重量轻,易于使用,并且能够在墓碑中存活。请确保您的密钥与所需密钥一样独特。
答案 4 :(得分:2)
如果您创建一个新的Windows Phone项目并使用 Windows Phone数据结构模板,您将完成大部分工作。
您要做的是设置ViewModel以包含您应用的所有数据。您可以使用IsolatedStorage序列化和反序列化此数据,以便在应用程序会话和逻辑删除时保存它。
在模板中,您会注意到 MailViewModel 和 ItemViewModel 。 MainViewModel存储应用程序所需的所有数据,包括ItemViewModel的ObservableCollection,ItemViewModel表示应用程序的单个数据类型。
在DetailsPage.xaml页面上,您需要将每个文本框的DataBind绑定到App.MainViewModel项目。如果希望ViewModel在用户操作DetailsPage.xaml上的数据时立即更新,请将绑定设置为TwoWay。您可以选择将Binding设置为OneWay,然后使用OK按钮将更改写回ViewModel并保存到IsolatedStorage。
以下是Binding的示例:
<TextBlock x:Name="ListTitle" Text="{Binding LineOne}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
在这种情况下,LineOne是ItemViewModel中的一个属性,当用户从MainPage.xaml中选择一个项目时,页面将从查询字符串中获取此数据。页面的DataContext阻止了数据绑定信息的来源。
以下是MainPage将所选项目从ViewModel传递给DetailsPage的片段。
// Handle selection changed on ListBox
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If selected index is -1 (no selection) do nothing
if (MainListBox.SelectedIndex == -1)
return;
// Navigate to the new page
NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative));
// Reset selected index to -1 (no selection)
MainListBox.SelectedIndex = -1;
}
以下是DetailsPage如何获取所选项目。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
DataContext = App.ViewModel.Items[index];
}
}
使用上面的默认模板,并提出任何其他问题。
数据绑定的优点和ObservableCollection是您可以只更新数据,而UX将反映这些更改。这是因为对数据的任何更改都会触发事件:
public string LineOne
{
get
{
return _lineOne;
}
set
{
if (value != _lineOne)
{
_lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
}
NotifyPropertyChanged()将此信息广播到View。
答案 5 :(得分:1)
您也可以保持简单并使用PhoneApplicationService.Current.State,它基本上是一个哈希表。如果你想要任何比应用程序更长的东西,你需要在隔离存储中实现自己的编组。
Omar建议使用Windows Phone数据绑定模板可能是此页面上的最佳选择。它与我的建议相同,但是你会得到更好的结果(更易于维护的代码),代价是更长的学习曲线。
我建议你按照我的方式去做,然后再做一次Omar的方式。
答案 6 :(得分:1)
因为我这样实施..无论是否正确我都不知道..
当您点击新闻列表页面时,它应该打开新闻详细信息页面。 我想将所选新闻项目内容从新闻列表页面传递到新闻详情页面。
新闻列表页面包含以下方法。
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
NewsDetailsPage newsDetailPage = (e.Content as NewsDetailsPage);
if (newsDetailPage != null)
newsDetailPage.SelectedNewsItem = SelectedNewsItem; //Contains the news details
base.OnNavigatedFrom(e);
}
在新闻详情页面。你可以访问那个(SelectedNewsItem)对象。
这可能是也可能不正确。
答案 7 :(得分:1)
一种选择是使用Application.Resources:
存储数据:
Application.Current.Resources.Add("NavigationParam", customers);
NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
检索数据
var customers = (List<Customer>) Application.Current.Resources["NavigationParam"];
这是一篇博文,更详细地介绍了这一点:http://mikaelkoskinen.net/windows-phone-pass-data-between-pages-application-resources/(作者:我)