是什么阻止了两个XAML页面之间的导航?

时间:2013-12-21 23:40:11

标签: xaml microsoft-metro visual-studio-2013 c++-cx

我在c ++ / cx XAML应用程序中遇到一个非常奇怪的错误: 我有一个后退按钮,用于检查您所取得的进度是否已保存,以及(如果不是)弹出一个弹出窗口,可让您保存或离开而不保存。但是,在两种情况下都使用this->frame->goBack()来完成:

当保存进度 时,应用暂停 __debugbreak() 然而,当 goBack() 弹出按钮上的按钮调用,一切正常。为什么会出现这种情况?

可能对您有用的事情:

该应用程序基于“空白应用程序”模板,页面本身基于Visual Studio 2013提供的“基本页面”模板

BoardPage.xaml中的控件定义如下:

<AppBarButton x:Name="backButton" Icon="Back" Height="95"
    Click="backButton_Clicked">
    <AppBarButton.Resources>
        <Flyout x:Key="WarningFlyoutBase">
            <Grid Height="150" Width="200">
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>
                <TextBlock Text="Unsaved progress, what do you want to do?"
                    HorizontalAlignment="Center" TextWrapping="Wrap" 
                    FontSize="14" Margin="4,10" TextAlignment="Center"/>
                <Button x:Name="WarningSaveButton"
                    Content="Save now." 
                    Grid.Row="1" HorizontalAlignment="Center"
                    Click="WarningSaveButton_Clicked"/>
                <Button x:Name="WarningLeaveButton"
                    Content="Leave without saving." 
                    Grid.Row="2" HorizontalAlignment="Center" 
                    Click="WarningLeaveButton_Clicked"/>
            </Grid>
        </Flyout>
    </AppBarButton.Resources>
    <AppBarButton.Flyout>
        <StaticResource ResourceKey="WarningFlyoutBase"/>
    </AppBarButton.Flyout>
</AppBarButton>

所以这三个控件(backButtonWarningSaveButtonWarningLeaveButton)都有各自的Clicked事件处理程序,但现在只有两个控件是相关的:

返回按钮:

void Tackle::BoardPage::backButton_Clicked(Platform::Object^ sender,
    Windows::UI::Xaml::RoutedEventArgs^ e)
{
    if (saved && Frame->CanGoBack) /* saved is a bool */
        this->Frame->GoBack();
    else
        backButton->Flyout->ShowAt((FrameworkElement^)sender);
}

注意:我也尝试将GoBack()替换为Navigate(TypeName(CreateGamePage::typeid)),但这没有帮助。

WarningLeaveButton:

void Tackle::BoardPage::WarningLeaveButton_Clicked(Platform::Object^ sender, 
    Windows::UI::Xaml::RoutedEventArgs^ e)
{
    if (Frame->CanGoBack)
        this->Frame->GoBack();
}

其他奇怪的东西:

我试图在很长一段时间内检查这次崩溃/调试的原因,并发现了以下内容:

  • 相关网页已导航至this->Frame->Navigate(TypeName(BoardPage::typeid), ref new CGameSession(job));。省略第二个参数可以神奇地修复崩溃。

  • App.g.hpp中触发断点时,打开价值errorMessage的观察值:

      

    “展示位置目标需要位于可视化树中。”

    Flyout是如何进入可视化树的,但它附加的Button不是?

  • 实际构建了目标网页 ,但NavigationHelper->OnNavigatedTo(e)方法在最后一行LoadState(this, ref new LoadStateEventArgs(e->Parameter, safe_cast<IMap<String^, Object^>^>(frameState->Lookup(_pageKey))));失败,因为LoadState()被调用似乎很奇怪容易且仅包含两个(void)类型转换。 (我没有修改过这些方法中的任何一种。)

1 个答案:

答案 0 :(得分:0)

这里的问题在于弹出窗口和事件处理程序与XAML-Controls一起使用的方式,有2个mayor点导致我的代码崩溃:

  1. 当点击或点击附加按钮时,会突然显示总是
  2. 事件处理程序似乎在显示弹出按钮之前执行
  3. 接下来是什么?

    好吧,当按下backButton时,backButton_Clicked会先被触发。 当游戏未保存时,弹出窗口会打开,您可以毫无问题地返回。 但是如果之前保存了游戏 ,事件处理程序会立即调用this->Frame->GoBack(),它会完全按照它应该做的,构建上一页,加载其状态并绘制它。
    但是之后,它会尝试打开弹出窗口,这就是问题:弹出窗口不再存在,因此出现奇怪的错误消息。

    我有点尴尬我花了很长时间才想出来,但也许有人会发现这有用,所以我会在这里留下这个问题。

    解决方法:

    我现在使用的解决方法是将FlyoutBase移动到<Page.Resources>并将其附加到大小为0x0 px的按钮。然后触发弹出按钮:Flyout::ShowAttachedFlyout(InvisibleButton);