BackRequested在UWP应用程序中不止一次触发

时间:2017-04-03 16:33:35

标签: webview uwp back-button back-button-control

我有一个应用程序,其中我主要有一个webview。我有问题。我已经制作了后退按钮来转到webview的上一个网页它工作正常,当它没有以前的页面时,它退出一个MessageBox(弹出窗口)。问题是,当我导航另一个页面并按回来时,它会递归触发后退按钮事件并显示MessageBox

 Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += (s, e) =>
        {
            e.Handled = true;
            if (Web_view.CanGoBack)
            {
                Web_view.GoBack();
                e.Handled = true;
            }
           else
            {
                quit();
                e.Handled = true;
            }
        };

以上是我的主页的代码

 private async void quit()
    {
        MessageDialog msg = new MessageDialog("Do you really want to quit?", "Quit");
        msg.Commands.Add(new UICommand("Yes") { Id = 0 });
        msg.Commands.Add(new UICommand("No") { Id = 1 });
        var ans = await msg.ShowAsync();
        if(ans.Id.Equals(0))
        {
            //System.Diagnostics.Debug.WriteLine("Exit");
            App.Current.Exit();
        }
    }

这是退出函数的代码。 我使用代码

导航到另一个页面
 private void about_Click(object sender, RoutedEventArgs e)
    {
        Frame.Navigate(typeof(BlankPage1));
    }

后面的blanckPage1代码是

 SystemNavigationManager.GetForCurrentView().BackRequested += (s,e)=>
        {
            e.Handled = true;
           // Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested -= BlankPage1_BackRequested;
           //System.Diagnostics.Debug.WriteLine("BackRequested");
            if (Frame.CanGoBack)
            {
                e.Handled = true;
                Frame.GoBack();
            }
            else
            {
                e.Handled = true;
            }
        };

为了更加清晰,例如当我打开应用程序时,webview导航到www.example.com,然后按照链接进入其他页面(例如www.example.com/link/firstlink)。然后我将我的框架导航到blankpage1,然后我会按回来。然后我们回到上一页(www.example.com/link/firstlink),它开始页面(www.example.com)并显示退出弹出窗口我该如何解决这个问题?

感谢您的所有重播。

1 个答案:

答案 0 :(得分:0)

您的问题是您仍然保留事件处理程序:在从BlankPage1导航回来的代码中,两个.BackRequested处理程序都被调用。您需要在离开时从MainPage上取消注册.BackRequested,例如:

的MainPage:

protected override void OnNavigatedTo(NavigationEventArgs e) {
    SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
}

protected override void OnNavigatedFrom(NavigationEventArgs e) {
    SystemNavigationManager.GetForCurrentView().BackRequested -= OnBackRequested;
}

private void OnBackRequested(object sender, BackRequestedEventArgs e) {
    // Your code to navigate back
    if (Web_view.CanGoBack)
    {
        Web_view.GoBack();
        e.Handled = true;
    }
    else
    {
        quit();
        e.Handled = true;
    }
}

在BlankPage1上也一样......虽然在App.xaml.cs中注册到BackRequested会更容易,你可以为整个应用程序处理(Window.Current.Content as Frame),这样的事情就像这样。使用接口使其成为“漂亮”的代码:

INavigationPage:

public interface INavigationPage {
    // When overriding the method returns true or false if the Page handled back request
    bool HandleBackRequested();
}

App.xaml.cs:

// ... Code before
protected override void OnLaunched(LaunchActivatedEventArgs e) {
    SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
}

private void OnBackRequested(object sender, BackRequestedEventArgs e) {
    Frame frame = Window.Current.Content as Frame;
    if (frame == null) return;

    INavigationPage page = frame.Content as INavigationPage;
    if (page == null) return;

    // Ask if the page handles the back request
    if (page.HandleBackRequested()) {
        e.Handled = true;
    // If not, go back in frame
    } else if (frame.CanGoBack) {
        e.Handled = true;
        frame.GoBack();
    }
}
// ... Code after

MainPage.xaml.cs中:

... class MainPage : Page, INavigationPage {
    // ... Code before

    // Implement the interface handling the backRequest here if possible
    public bool HandleBackRequested() {
        if (Web_view.CanGoBack) {
            Web_view.GoBack();
            return true;
        }
        return false;
    }

    // ... Code after
}

然后BlankPage不需要任何代码,也不需要订阅.BackRequested。