【问题标题】:What prevents a Navigation between two XAML-pages?是什么阻止了两个 XAML 页面之间的导航?
【发布时间】:2013-12-21 23:40:10
【问题描述】:

我在我的 c++/cx XAML 应用程序中遇到了一个非常奇怪的错误: 我有一个后退按钮,用于检查您所做的进度是否已保存,并且(如果没有)弹出一个弹出框,让您保存或离开而不保存。这在这两种情况下都是通过this->frame->goBack() 完成的,但是:

当进度保存时,应用程序会在 __debugbreak() 暂停 goBack() 弹出按钮,一切正常。为什么会这样呢?

可能对您有帮助的事情:

应用基于“Blank App”模板,页面本身基于Visual Studio 2013提供的“Basic Page”模板

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-&gt;Frame-&gt;Navigate(TypeName(BoardPage::typeid), ref new CGameSession(job)); 导航到相关页面。省略第二个参数可以神奇地修复崩溃。

  • 当在App.g.hpp 中触发断点时,打开对值errorMessage 的监视显示:

    “放置目标需要在可视化树中。”

    为什么 Flyout 在可视化树中,但它所附加的 Button 却不在?

  • 目标页面实际上构造的,但是NavigationHelper-&gt;OnNavigatedTo(e)方法在最后一行LoadState(this, ref new LoadStateEventArgs(e-&gt;Parameter, safe_cast&lt;IMap&lt;String^, Object^&gt;^&gt;(frameState-&gt;Lookup(_pageKey))));失败,这看起来特别奇怪,因为LoadState()很容易被调用并且只包含两个@ 987654339@ 类型转换。 (我没有修改任何一种方法。)

【问题讨论】:

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


    【解决方案1】:

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

    1. 浮出控件始终在单击或点按附加到的按钮时显示。
    2. 事件处理程序似乎在显示浮出控件之前执行。

    接下来会发生什么?

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

    我有点尴尬,我花了这么长时间才弄明白,但也许将来有人会发现这很有用,所以我将把这个问题留在这里。

    解决方法:

    我现在使用的解决方法是将 FlyoutBase 移动到 &lt;Page.Resources&gt; 并将其附加到大小为 0x0 像素的按钮上。然后像这样触发弹出窗口:Flyout::ShowAttachedFlyout(InvisibleButton);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      相关资源
      最近更新 更多