Как сделать переход между окнами wpf

Обновлено: 06.07.2024

В качестве CurrentControl буду подставлять различные UserControl, которые представляют собой окна приложения.
Для этого MainWindow создаю свою MainViewModel, которая будет управлять всеми окнами в приложении.
Сначала создаю базовый класс ViewModelBase, от которого будут наследоваться все ViewModel приложения, чтобы реализовать интерфейс INotifyPropertyChanged.

вы хотите в модели представления хранить представление и подставлять его структуру главного окна? Что-то как-то замороченно и сомнительно.

Попробуйте сделать так. В модели представления главного окна хранятся модель представления меню этого окна и модель представления для ContentControl. Смена содержимого CurrentControl происходит через отдачу команды из представления меню в модель представления меню, которая изменяет модель представления для CurrentControl (назовём это "событие А"). Для каждой модели представления, которая будет в CurrentControl, сделайте своё представление в виде DataTemplate. Тогда при событии А нужное представление подставится в ContentControl автоматически.

И чем тебе не нравится MVVM? Его VM-V часть в WPF сделана просто отлично, а с помощью пары полезных подключаемых библиотек получается дополнительный функционал поведений и расширенные команды - вообще конфетка.

, то в WPF это далеко не так очевидно.

Я совершенно не спорю что мой код велосипедный, однако это единственное на мой взгляд что может заработать.
Поэтому и создал пост, чтобы люди посоветовали как они справлялись с данной задачей или имеют какие-либо размышления.
Насчет подхода с DataTemplate- если есть 30 различных view, то их нужно все включить изначально?

есть 100500 примеров многооконных приложений в WPF, где можно вызвать открытие окна из любого слоя.
Лично я использую самописное, у меня это примерно так работает:
есть Standalone менеджер окон, в котором я вызываю метод OpenDialog или OpenWindow, а в качестве параметра передаю объект модели представления (viewmodel), WM ищет на основе типа модели стиль для окна, создает окно, применяет к нему этот стиль.
То есть, для открытия окна мне нужно знать только модель представления.
Так же после создания окна к нему сразу добавляются обработчики команд, на закрытие, подтверждения и прочее, чтоб связать это с моделью.
В стиле окна я определяю шаблон окна, если нужно, параметры и прочее.
Но есть и другие способы, не менее удобные.

, то в WPF это далеко не так очевидно.

Я совершенно не спорю что мой код велосипедный, однако это единственное на мой взгляд что может заработать.
Поэтому и создал пост, чтобы люди посоветовали как они справлялись с данной задачей или имеют какие-либо размышления.
Насчет подхода с DataTemplate- если есть 30 различных view, то их нужно все включить изначально?

Вам надо только понять суть, которую я выделил жирным. И то, что во всех стандартных гайдах - да, вы правы - есть только способ однооконного приложения со сменой представлений через DataTemplate. Что-то другое придётся искать или придумывать самому.

Вот способ реализации настроек в виде дерева (программа Download Master). Посмотрите, может, вам такое подойдёт. В последовательности диалоговых окон каждое окно соответствует ветке дерева. Суть та же, только дерево компактнее и нагляднее. Подробные настройки справа - это конкретные настройки в текущей подкатегории. Т. е. весь ваш граф вызовов диалоговых окон можно отобразить на такое дерево, и, на мой взгляд, это будет лучше, чем 30 различных диалоговых форм, которые, пооткрывав, будут загромождать весь экран, а потом их ещё и закрывать надо.

попробуйте как я вам сказал
у меня в App.xaml хранятся ссылки на все ресурсные файлы со стилями всех окон.
ключем для них будет тип модели
вот так:

есть класс
WindowManager
который в методе OpenWindow
находит в ресурсах приложения модель MainModel, которая наследована от интерфейса IWindowModel (который определен в пространстве имён WindowManager) и который позволяет управлять окном из модели представления (обрабатывать события закрытия окна и блокировать их, сворачивания, разварачивания и т.д.)
создает объект Window, задает ему найденный стиль, если стиль не найден, окно не открывается, а выдается соотвествующий Exception.
затем WindowManager обёртывает окно в отдельный Wrapper который поддерживает иерархию окон, для каскадного закрытия и т.д.

Какие плюсы:
мы можем открывтаь и закрыывать окна прямо в ViewModel, при этом ViewModel ни чего не знает ни об окнах, ни о стилях и т.д.
в ресурсах мы можем быстро найти какое окно (стиль окна) предназначен для какой модели представления, так как мы связываем их по типу.
Мы можем легко из любой точки программы закрыть окно для нужно нам модели просто передав в процедуру закрытия только ссылку на модель.
с помощью WM мы контролируем весь геморой с окнами

Какие минусы:
- не все свойства можно определить для окна через стиль, но всегда можно это решить опять же через WM
- для 1 модели представления мы можем задать только 1 стиль, так как нельзя создать 2 стиля с 1 типом они либо будут перекрывать друг друга либо конфликтовать, но это опять же можно решить через WM (перегрузить метод открытия с указанием ключа стиля)
- для того, чтоб открыть окно которое будет диалоговым, блокировать parent\owner нужно явно указать либо ссылку на экземляр VM, что может быть не всегда удобно. Но в WM есть свойства MainWindowModel и CurrentWindowModel можно открывая окна привязаться к ним.

точно так же я обычно делаю и с Page'ами, каждая модель Page'а наследуется от какого то базового класса или интерфейса аля IMyPage, затем для каждой странички я создаю свой
В качестве контейнера работает ContentPresenter или ContentControl, в котором определен DataTemplateSelector, который в свою очередь ищет у себя в коллекции шаблоны, либо в ресурсах приложения и т.д. Находит и задает соотвествующий шаблон.

Главное, что вы сначала моделируете свой интерфейс в специальном слое, прорабатываете его логику на языке программирования, а только потом на формы его накидываете. После проработки логики интерфейса в классах, вы можете на эти классы нацепить любой вид этого интерфейса - любые представления, любую организацию форм, в наших терминах.

Я ещё раз говорю - кто вам сказал, что у вас именно ФОРМЫ? Может, у вас какой-то шаблон, которым вы мыслите, и кроме кучи вызываемых друг из друга форм вам трудно представить что-то другое? Попробуйте продумать сначала свой интерфейс логически, без связи с кучей форм. И тогда, возможно, вы придумаете, что есть организация UI получше (если она действительно есть).

Поэтому я попытался перейти на другую страницу wpf, но она не работает вообще. Вот то, что я использовал:

Большая проблема заключается в том, что Visual Studio говорит, что в NavigationService нет навигации.

Может ли кто-нибудь сказать мне, что я делаю неправильно?

enter image description here

Полный код см. на рисунке ниже:

Я бы предложил использовать this указатель и указать на ваши routedeventargs.

Что делается в первую очередь? Правильно, на кнопку вешается event, а далее в code-behind пишется код перехода на новую страницу.

XAML:
Code-behind:

Как все это сделать проще и в одном месте (в XAML-коде)?
Для начала подключаем к проекту сборки:

  • System.Windows.Interactivity
  • Microsoft.Expression.Interactivity


А теперь осталось написать переход на другую страничку чистым XAML :)

Теперь не нужно делать много однотипных code-behind операций и жить станет несколько проще :)

Microsoft Logo

Gray Pipe

Приносим извинения. Запрошенное содержимое было удалено. Вы будете автоматически перенаправлены через 1 секунду.

Лучший отвечающий

Вопрос

Всем привет. Возникла такая проблема.

Есть две формы, необходимо сделать так, чтобы по клику на кнопку на первой форме - появлялась вторая, а первая скрывалась. А по клику на кнопку на второй форме - вторая закрывалась, а первая появлялась.

Пробовал делать несколькими вариантами:

Данный вариант не работает - первая форма не выходит из состояния невидимости.

Вот второй вариант:

Этот вариант работает, но неверно. Почему-то на команду

Создаётся новый экземпляр Form2. А Form2 - главная форма приложения и в данном случае закрывая заново созданную форму 2 - приложение не закрывается, т.е. изначально созданная Form2 висит в невидимости.

Читайте также: