2017-08-30 11 views
0

J'ai la configuration suivante: Un MainPage xaml-view et un SettingPage xaml-view. Dans le xaml-view SettingPage j'ai activé le bouton de retour qui est dans la barre de titre de la fenêtre et j'ai ajouté un BackRequestedEventArgs. (En outre, j'ai une page xaml DX12 mais il n'est pas encore impliqué dans la navigation, donc il ne sera jamais initialisé.)UWP - Platform :: DisconnectedException lors de la navigation entre les pages

Donc mon problème est: si je clique sur un flyoutitem appelé paramètres qui se trouve dans la MainPage, Je vais me diriger vers la page SettingPage. Le bouton de retour apparaît dans la barre de titre et si je clique dessus, je reviens à la MainPage. Maintenant, je le fais encore une fois: en cliquant sur les paramètres, naviguez vers SettingPage. Maintenant, si je clique sur le bouton Précédent ou ferme la fenêtre, l'application se bloque et me montre l'exception suivante:

Plate-forme :: DisconnectedException^à 0x046BED80. HRESULT: 0x80010108

Ma question: Comment résoudre ce problème?

Voici mon code pour elle:

MainPage Navigation:

void MainPage::MenuFlyoutItemSettings_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) 
    { 

    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingsPage::typeid)); 

    } 

page Paramètres:

// in Constructor 
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->AppViewBackButtonVisibility = Windows::UI::Core::AppViewBackButtonVisibility::Visible; 
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> 
    BackRequested += ref new Windows::Foundation::EventHandler< 
    Windows::UI::Core::BackRequestedEventArgs^>(
     this, &SettingsPage::App_BackRequested); 



void SettingsPage::App_BackRequested(
    Platform::Object^ sender, 
    Windows::UI::Core::BackRequestedEventArgs^ e) 
{ 
    Windows::UI::Xaml::Controls::Frame^ rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content); 
    if (rootFrame == nullptr) 
     return; 

    // Navigate back if possible, and if the event has not 
    // already been handled. 
    if (rootFrame->CanGoBack && e->Handled == false) 
    { 
     e->Handled = true; 
     rootFrame->GoBack(); 
    } 
} 

outre les deux méthodes ont onSuspending et gestionnaires onResuming ajoutés par moi manuellement, mais ils sont les deux vides:

//in constructor 

    Application::Current->Suspending += ref new SuspendingEventHandler(this, &SettingsPage::OnSuspending); 
    Application::Current->Resuming += ref new EventHandler<Object^>(this, &SettingsPage::OnResuming); 


void SettingsPage::OnSuspending(Object^ sender, SuspendingEventArgs^ e) { 


} 

void SettingsPage::OnResuming(Object^ sender, Object^ e) { 


} 

REMARQUE: Si je supprime tout le code de retour, l'application ne se bloque jamais avec cette exception, donc je pense que c'est une erreur dans ce code.

EDIT 04/09/2017:

Après avoir travaillé sur Sunteen Wu - MSFT Réponse de en bas j'ai réalisé que même si je supprime tous les backbutton-code que je vais faire cette exception dès que je rentre dans la ParamètresPage la première fois et fermez l'application. Voici donc mon scénario actuel où je reçois l'exception décrite:

Le code que j'ai maintenant pour la navigation:

MainPage (dans un settingsbutton personnalisé):

this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingsPage::typeid)); 

page Paramètres (dans un backbutton personnalisé):

this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(MainPage::typeid)); 

Ainsi, après la première fois que je navigue sur le en appuyant sur la page Paramètres settingsbutton je reçois l'exception décrite seulement si je shutdown e e app (même chose si vous cliquez sur x rouge ou si vous arrêtez le débogueur). La navigation fonctionne bien, je peux échanger entre les pages aussi longtemps que je veux et je ne recevrai pas l'exception lors de l'exécution de l'application.

RÉPONSE FINALE 06/09/2017:

La combinaison Sunteen Wu - MSFT de la réponse à la suppression mentionnés ci-dessus

Application::Current->Suspending += ref new SuspendingEventHandler(this, &SettingsPage::OnSuspending); 
Application::Current->Resuming += ref new EventHandler<Object^>(this, &SettingsPage::OnResuming); 

gestionnaires est la solution pour moi. Maintenant, il n'y a pas d'exception Disconnected et la fonction Back-Button-Logic fonctionne également!

Répondre

0

Plate-forme :: DisconnectedException^à 0x046BED80. HRESULT: 0x80010108

En fait, vous rencontrez le problème cycles. Pour ce que les cycles question et comment résoudre s'il vous plaît référence Weak references and breaking cycles (C++/CX). Vous avez rencontré le problème de cycles lorsque vous vous abonnez le handle d'événement BackRequested. Avec le WeakReference, vous trouverez la question:

WeakReference wr(this); 
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> 
    BackRequested += ref new Windows::Foundation::EventHandler< 
    Windows::UI::Core::BackRequestedEventArgs^>([wr](
     Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e) 
{ 
    SettingsPage^ c = wr.Resolve<SettingsPage>(); 
    if (c != nullptr) 
    { 
     Windows::UI::Xaml::Controls::Frame^ rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content); 
     if (rootFrame == nullptr) 
      return; 
     if (rootFrame->CanGoBack && e->Handled == false) 
     { 
      e->Handled = true; 
      rootFrame->GoBack(); 
     } 
    } 
    else 
    { 
     throw ref new DisconnectedException(); 
    } 
}); 

de l'article, lorsqu'un gestionnaire d'événements jette DisconnectedException, il provoque l'événement pour supprimer le gestionnaire de la liste d'abonnés. Ainsi, pour le résoudre, vous pouvez supprimer le handle d'événement de la liste des abonnés après la demande de retour. L'extrait de code suivant a montré comment supprimer.

Windows::Foundation::EventRegistrationToken cookie; 
SettingsPage::SettingsPage() 
{ 
    InitializeComponent(); 
    ... 
    cookie = Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> 
     BackRequested += ref new Windows::Foundation::EventHandler< 
     Windows::UI::Core::BackRequestedEventArgs^>(
      this, &SettingsPage::App_BackRequested);  
} 

void SettingsPage::App_BackRequested(
    Platform::Object^ sender, 
    Windows::UI::Core::BackRequestedEventArgs^ e) 
{ 
    ... 
    Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> 
     BackRequested -= cookie; 
} 

De plus, je vous recommande de vous abonner à cet événement à l'intérieur App.xaml.cpp pour éviter ce problème. Vous pouvez vous abonner à l'intérieur OnLaunched comme suit:

void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) 
{ 
    auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content); 
    // Do not repeat app initialization when the Window already has content, 
    // just ensure that the window is active 
    if (rootFrame == nullptr) 
    { 
    ... 
    } 
    else 
    { 
     ... 
    }  
    Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> 
     BackRequested += ref new Windows::Foundation::EventHandler< 
     Windows::UI::Core::BackRequestedEventArgs^>(
      this, &App::App_BackRequested); 
} 

void App::App_BackRequested(
    Platform::Object^ sender, 
    Windows::UI::Core::BackRequestedEventArgs^ e) 
{ 
    ... 
} 

Plus de détails vous pouvez faire référence BackButton échantillon officiel.

+0

Merci pour l'explication, le seul problème qui reste est que, après la première fois que je navigue vers les paramètres, si je ferme l'application après cela, je reçois toujours "Platform :: DisconnectedException^à 0x047FF328 HRESULT: 0x80010108" (mais pas après le second arrière, plus jamais après back-navigation). J'ai utilisé votre extrait de "cookie" dans SettingsPage.xaml.cpp (ajouté le gestionnaire via cookie = ... et dans le AppBackRequested j'ai utilisé mon code de la question en ajoutant votre - = ligne de cookie) et j'ai utilisé votre dernier extrait dans App. xaml.cpp. – David

+0

@David, Pourriez-vous s'il vous plaît juste essayer l'extrait dans 'App.xaml.cpp'? (Supprimer les codes à l'intérieur de la page de configuration). –

+0

J'ai supprimé tout le code pertinent dans la page settings, j'ai écrit le cookie = (...) dans onLaunched() depuis App.xaml.cpp et j'ai écrit le code méthode AppBackRequested que j'avais dans ma question plus votre (..) - = cookie dans App.xaml.cpp. Maintenant, je peux aller la première fois en arrière, sur la deuxième fois en naviguant vers la page de configuration, je ne peux pas revenir à MainPage - en cliquant sur le bouton de retour rien ne se passe. En outre, l'exception après la fermeture de l'application est toujours là comme dans mon commentaire avant. – David