UWP — Platform :: DisconnectedException при навигации по страницам

У меня есть следующие настройки: xaml-представление MainPage и xaml-представление SettingPage. В xaml-представлении SettingPage я активировал кнопку «Назад», которая находится в строке заголовка окна, и добавил BackRequestedEventArgs. (Более того, у меня есть страница XXL DX12, но она еще не связана с навигацией, поэтому она никогда не будет инициализирована.)

Итак, моя проблема: если я нажму на элемент flyout, называемый settings, который находится на главной странице, я перейду на SettingPage. В заголовке появляется кнопка, и если я щелкаю по ней, я возвращаюсь на главную страницу. Теперь я делаю это еще раз: нажимая на настройки, переходя к SettingPage. Теперь, если я нажимаю на кнопку ИЛИ закрываю окно, приложение вылетает и показывает следующее исключение:

Platform :: DisconnectedException ^ в 0x046BED80. HRESULT: 0x80010108

Мой вопрос: как мне это исправить?

Вот мой код для этого:

Главная страница навигации:

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

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

}

SettingsPage:

 // 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();
}
}

Кроме того, оба метода имеют обработчики onSuspending и onResuming, добавленные мной вручную, но они оба пусты:

//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) {}

ПРИМЕЧАНИЕ. Если я удаляю весь код кнопки, приложение никогда не завершает работу с этим исключением, поэтому я считаю, что в этом коде ошибка.

РЕДАКТИРОВАТЬ 2017-09-04:

После работы над Sunteen Wu — ответ MSFT снизу я понял, что даже если я удалю весь код кнопки, я получу это исключение, как только в первый раз войду в страницу настроек и закрою приложение. Итак, вот мой текущий сценарий, где я получаю описанное исключение:

Единственный код, который я получил сейчас для навигации:

MainPage (в пользовательской настройке):

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

SettingsPage (в пользовательской кнопке):

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

Таким образом, после первого перехода на страницу настроек нажатием кнопки настроек я получаю описанное исключение, только если я выключаю приложение (то же самое, если нажать на красный крестик или остановить отладчик). Навигация работает нормально, хотя, я могу переключаться между страницами, сколько захочу, и я не получу исключение при запуске приложения.

ЗАКЛЮЧИТЕЛЬНЫЙ ОТВЕТ 2017-09-06:

Объединение Sunteen Wu — MSFT’s Answer с удалением вышеупомянутого

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

Хендлеры это решение для меня. Теперь нет Disconnectedexception, и Back-Button-Logic также работает!

0

Решение

Platform :: DisconnectedException ^ в 0x046BED80. HRESULT: 0x80010108

На самом деле вы встречаете циклы вопрос. Для чего это проблема циклов и как решить, пожалуйста, ссылку Слабые ссылки и разрывы циклов (C ++ / CX). Вы столкнулись с проблемой циклов при подписке BackRequested дескриптор события. С WeakReference вы найдете вопрос:

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();
}
});

Из статьи, когда обработчик события выбрасывает DisconnectedException, это вызывает событие, чтобы удалить обработчик из списка подписчиков. Чтобы решить эту проблему, вы можете удалить дескриптор события из списка подписчиков после обратного запроса. Следующий фрагмент кода показал, как удалить.

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;
}

Кроме того, я рекомендую вам подписаться на это событие внутри App.xaml.cpp чтобы избежать этой проблемы. Вы можете подписаться внутри OnLaunched как следует:

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)
{
...
}

Более подробную информацию вы можете ссылаться Кнопка назад официальный образец.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]