我有一个像这样定义的数据透视页面:
<Grid x:Name="LayoutRoot" Background="Transparent" >
<Pivot Title="JOETZ">
<PivotItem Header="kampen" Name="PvOne">
<views:CampsPage/>
</PivotItem>
<PivotItem Header="kalender" Name="PvTwo">
<views:CalendarPage/>
</PivotItem>
<PivotItem Header="profiel" Name="PvThree">
<views:LoginPage/>
</PivotItem>
</Pivot>
</Grid>
以第一页(CampsPage
)为例:它包含一个ListBox
,其中包含阵营的概述。单击某个项目时,应该转到详细视图。为了导航,我认为这应该已经足够了:
Frame.Navigate(typeof(CampDetail), selectedCamp);
但这会引发NullReferenceException
,因为Frame
显然是null
。
另一方面,像这样的导航工作:
var frame = Window.Current.Content as Frame;
if (frame == null) { return; }
frame.Navigate(typeof(CampDetail), selectedCamp);
这种做法也是如此:
var frame = ((App) Application.Current).RootFrame;
frame.Navigate(typeof(CampDetail), selectedCamp);
为什么不在枢轴项目中设置Frame
属性?作为后续内容:我应该如何从枢轴项目导航?
答案 0 :(得分:3)
您似乎已经找到了所需的大部分信息。我可以确认这是导航的方式(正如你自己建议的那样):
var frame = (Frame)Window.Current.Content;
frame.Navigate(typeof(CampDetail), selectedCamp);
以这种方式获取Frame
非常常见且安全。除{em>你将其放在那里之外,Frame
中的Window.Current.Content
除了Frame
之外什么都不会。在这种情况下,根本不会成为Window.Current.Content
,你无论如何都无法像这样导航(也就是说,你必须手动更改{{1}显示其他内容的属性,并手动管理后退按钮。)
一些想法/建议
我建议您使用静态Navigate
方法创建一个静态类,它可以完成工作(获取Frame并调用其Navigate
方法)。
或许更方便的是(也)为执行导航的UserControl类创建扩展方法。这样您只需在所有UserControls中调用this.Navigate(typeof(CampDetail), selectedCamp)
。
我还建议保持一致并始终使用此方法,并且永远不要使用Page.Frame
属性(除非您确实需要,出于某种原因)。
这将使查找/解决与导航相关的问题更容易,因为每个导航都将通过该方法。
您应该使用UserControl而不是Page
Page
是要在整个屏幕上显示的应用的一部分。它不是另一页的一部分。你使用它的方式,就像UserControl一样(在这种情况下你应该使用它)。 Page
特定功能仅在您使用Frame
对象导航到该功能时才有效。
用户控件和模板化控件是页面的可重用部分。因此,如果您需要在多个页面中拥有一些UI(及其功能),您可以制作其中一个控件。
因此,我建议您将<views:CampsPage/>
,<views:CalendarPage/>
和<views:LoginPage/>
更改为UserControls而不是Pages。如果您还需要页面(用于导航),请创建仅显示这些UserControls的页面。
硬件返回按钮
你似乎不再需要这个了,但我还是会说几行。
默认情况下,返回按钮只是告诉关闭应用。您可以使用Frame
中的Window.Current.Content
GoBack()
,如果可能HardwareButtons.BackPressed
事件手动处理后退按钮并执行一些非默认操作。
修改强>
我对后退按钮的默认操作错了并修复了它。我很确定它曾经自动导航回堆栈。
答案 1 :(得分:1)
我不确定这是不是最好的答案(我确定不是:)但应该有效。
问题是CampsPage
是我怀疑 Page 类在 Frame 之外的其他容器中。您尚未导航到该页面,它不在Window.Current.Content
内 - 它位于 Pivot 中。因此, Frame 属性为null
。
这是我的丑陋的方法:
使用 DependencyProperty 扩展 Page 类 - 对父页面的引用:
public class ExtendedPage : Page
{
public Page ParentPage
{
get { return (Page)GetValue(ParentPageProperty); }
set { SetValue(ParentPageProperty, value); }
}
public static readonly DependencyProperty ParentPageProperty =
DependencyProperty.Register("ParentPage", typeof(Page), typeof(Page), new PropertyMetadata(0));
}
然后制作CampsPage
(和其他)此扩展页类型。然后将 ParentPage 属性绑定到框架内的当前 Page :
<Page Name="MyMainPage" ... rest of things ...>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Pivot Title="JOETZ">
<PivotItem Header="kampen" Name="PvOne">
<local:CampsPage ParentPage="{Binding ElementName=MyMainPage}"/>
</PivotItem>
... rest of the code
然后您可以在CampsPage
中导航:
ParentPage.Frame.Navigate(typeof(DetailPage));
就像我说的那样,可能有更好的解决方案,但除非没有别的,否则这可能会有用。
您can download from GitHub的一个例子。