Главная » WPF » Управление навигацией WPF

0

В предыдущем примере есть одна проблема: пользователь может покинуть первую страницу,  не введя имя. При работе с объектом  Window мы можем вос# пользоваться событием Closing (или любым другим способом выявления попыт# ки закрытия окна), чтобы не дать пользователю закрыть  диалоговое  окно, не за# полнив обязательные поля.

Эквивалентная функциональность имеется в классе NavigationService:

public class NavigationService

{

public event LoadCompletedEventHandler LoadCompleted;

public event NavigatedEventHandler Navigated;

public event NavigatingCancelEventHandler Navigating;

public event NavigationProgressEventHandler NavigationProgress;

public event NavigationStoppedEventHandler NavigationStopped;

}

Событие Navigating  позволяет  отменить переход точно так же, как отменяет# ся закрытие  окна. Поскольку в классе Page нет такого же простого события, как Window.Closing, придется  немного потрудиться. Причина довольно  тонкая,  но существенная. Когда мы подписываемся на событие Navigating, мы сохраняем указатель  на наш объект в объекте NavigationService, являющемся частью нави# гационного узла. Если не разорвать эту связь, то страница будет храниться в па# мяти вечно. Тут возникает  небольшая  сложность; поскольку  по завершении на# вигации  доступа к объекту NavigationService уже нет, ссылку на него необходи# мо запомнить.

Рассмотрим код для реализации контроля на нашей странице. Первым  делом подпишемся на событие Loaded объекта Page. Это событие будет возникать  при каждом переходе на данную страницу:

<!— name.xaml —>

<Page … x:Class=’EssentialWPF.Name’ Text=’Who are you?’ Loaded=’PageLoaded’

</Page>

В обработчике  события Loaded нужно сделать две вещи: подписаться на инте#

ресующие нас события и кэшировать объект NavigationService:

NavigationService _navigation;

void PageLoaded(object sender, EventArgs e) {

_navigation = this.NavigationService;

_navigation.Navigating += Page_Navigating;

_navigation.Navigated += Page_Navigated;

}

Мы подписались на событие Navigated просто для того, чтобы вовремя отказать#

ся от подписки на другие события и обнулить ссылки во избежание утечек памяти:

void Page_Navigated(object sender, NavigationEventArgs e) {

_navigation.Navigating  = Page_Navigating;

_navigation.Navigated  = Page_Navigated;

_navigation = null;

}

И, наконец, перейдем к обработчику события Navigating, в котором и произво#

дится контроль:

void Page_Navigating(object sender, NavigatingCancelEventArgs e) {

if (_nameBox.Text.Length == 0) {

e.Cancel = true;

}

}

Это код не даст покинуть страницу, пока не будет введено имя. Запустив прог# рамму, попробуйте щелкнуть по кнопке Вперед  в окне навигации после того, как нажмете  кнопку  Назад на странице  «Hello».  После  возврата  назад  поле имени окажется  пустым, и, следовательно, попытка перейти вперед не увенчается  успе# хом. Поскольку мы хотим перейти  на ту страницу,  где уже были, следовало  бы отключить контроль. Небольшая модификация позволит распознать этот случай:

void Page_Navigating(object sender, NavigatingCancelEventArgs e) {

if (e.NavigationMode == NavigationMode.New &&

_nameBox.Text.Length == 0) {

e.Cancel = true;

}

}

Источник: К. Андерсон  Основы  Windows Presentation Foundation. Пер. с англ. А. Слинкина — М.: ДМК Пресс, 2008 — 432 с.: ил.

По теме:

  • Комментарии