Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 254

MVVM работа с несколькими окнами

23.08.2024, 14:26. Показов 1129. Ответов 15

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскажите.
Как настроить работу с 2 окнами в WPF MVVM. Суть: есть главное окно и его MainViewModel по нажатию на кнопку отправить, срабатывает команда, которая запускает второе окно с его SecondViewModel и там пользователю надо выбрать нужный пункт и нажать кнопку "Выбрать".
Второе окно нужно чтобы пользователь выбрал 1 из нескольких вариантов, из этого выбора будет получен id. Нужно чтобы пока пользователь не выбрал 1 из вариантов и не нажал кнопку во втором окне первое было заблокировано и ждало (чтоб вычисления дальше не шли).
В SecondViewModel есть свойство
C#
1
public int Id{ get; set; }
, в которое записывается Id из нажатого пользователем RadioButton, а нажатие на кнопку по сути просто закрывает второе окно и дает MainViewModel информацию о том что пользователь что-то выбрал.
Окна у меня это UserControl.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public ICommand SendCommand { get; }
private bool CanSendCommand(object p) =>
    true;
private void OnSendCommand(object p)
{
  Choose();
}
 
private int Choose()
{
    var id = 0;
    _secondViewModel  = new SecondViewModel ();
    var window = new Window();
    window.Content = new SecondView(window);
    window.DataContext = _secondViewModel;
    window.Closed += (sender, e) => id =_secondViewModel.Id;
    window.Show();
    
    return id;
}
пробовал так но код просто пробегает весь метод и всегда возвращает 0
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.08.2024, 14:26
Ответы с готовыми решениями:

MVVM работа с окнами
Подскажите пожалуйста в чем и где моя ошибка? В главном окне через viewmodel подключаюсь к локальной базе, по нажатию на кнопку меню, через...

Управление окнами MVVM
У меня есть сервис открытия/закрытия окон, я передаю туда тип VM, не передаю саму VM так как контекст всем окнам уже присвоен через...

Программа с несколькими окнами
Создала программу с основным окном MainWindow, в методе вызываю другое окно BD_add. В BD_add вызываю значение переменных из MainWindow. В...

15
 Аватар для Andrey-MSK
3312 / 2199 / 387
Регистрация: 14.08.2018
Сообщений: 7,400
Записей в блоге: 4
23.08.2024, 15:03
IIIIIIIIIgor, Пробуйте - Создание диалоговых окон, согласно паттерну MVVM
1
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 254
23.08.2024, 15:11  [ТС]
Спасибо, помогло открывать окно как диалог
C#
1
window.ShowDialog();
0
 Аватар для Andrey-MSK
3312 / 2199 / 387
Регистрация: 14.08.2018
Сообщений: 7,400
Записей в блоге: 4
23.08.2024, 15:15
IIIIIIIIIgor, Я вам показал
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
Как настроить работу с 2 окнами в WPF MVVM
...
Где у вас вот это находится?
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
C#
1
2
3
4
private void OnSendCommand(object p)
{
 Choose();
}
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 254
23.08.2024, 15:37  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Где у вас вот это находится?
в MainViewModel
0
 Аватар для Andrey-MSK
3312 / 2199 / 387
Регистрация: 14.08.2018
Сообщений: 7,400
Записей в блоге: 4
23.08.2024, 15:50
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
в MainViewModel
А откуда тогда там вот это?
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
C#
1
2
3
4
5
var window = new Window();
 window.Content = new SecondView(window);
 window.DataContext = _secondViewModel;
 window.Closed += (sender, e) => id =_secondViewModel.Id;
 window.Show();
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 254
23.08.2024, 15:52  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
А откуда тогда там вот это?
это все находится в MainViewModel. приватный метод Choose, который создает второе окна, вызывается командой привязанной к кнопке на главном окне
0
 Аватар для Andrey-MSK
3312 / 2199 / 387
Регистрация: 14.08.2018
Сообщений: 7,400
Записей в блоге: 4
23.08.2024, 16:08
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
это все находится в MainViewModel
В паттерне MVVM во ViewModel не должно быть даже упоминания объектов View, от слова совсем. Это прямое нарушение паттерна...
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,037
Записей в блоге: 2
23.08.2024, 18:59
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
MVVM работа с несколькими окнами
Сколько окон - для паттерна не важно. Может быть одно, может 10, а может и ни одного. Это всё детали реализации View, которые паттерном не регламентируются.

View зависима от ViewModel. В основном через привязку к свойствам, но могут быть и другие зависимости: прослушка событий, внедрение делегатов обратного вызова, инжекция зависимостей и др.
Когда VM меняет своё состояние, то либо View замечает это изменение и открывает сколько нужно окон, либо VM активирует какую-то внедрённую зависимость, например, вызывает делегат метода открывающего окно.

Добавлено через 3 минуты
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
var window = new Window();
Ну, здесь я полностью согласен с Andrey-MSK, никаких View типов в VM не должно быть. Даже ссылок на библиотеки с UI элементами быть не должно. В идеале VM должна создавать в платфомонезависимом проекте (Standard).
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3384 / 2704 / 573
Регистрация: 04.09.2018
Сообщений: 8,514
Записей в блоге: 3
23.08.2024, 19:22
Andrey-MSK, думаю, для тех кто "не в теме", применять подход с DI будет выглядеть слишком сложным для понимания. Повторить смогут, а вот поменять что-либо уже нет...
Для начала, можно просто передавать в VM некий сервис по вызову нужных окон через интерфейс. А в реализации этого интерфейса уже сам вызов окна.
2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,037
Записей в блоге: 2
24.08.2024, 00:42
Цитата Сообщение от wizard41 Посмотреть сообщение
Для начала, можно просто передавать в VM некий сервис по вызову нужных окон через интерфейс.
Согласен.

Добавлено через 4 минуты
IIIIIIIIIgor, самое простое:

В VM свойство и метод:
C#
1
2
3
public Func<int> Choose {get; set;}
 
private int ChooseExecute() => Choose();
В View:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
MainViewModel mainVM = ....;
mainVM.Choose  = () =>
{
    var id = 0;
    _secondViewModel  = new SecondViewModel ();
    var window = new Window();
    window.Content = new SecondView(window);
    window.DataContext = _secondViewModel;
    window.Closed += (sender, e) => id =_secondViewModel.Id;
    window.Show();
    
    return id;
};
Добавлено через 4 часа 58 минут
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
_secondViewModel  = new SecondViewModel ();
    var window = new Window();
    window.Content = new SecondView(window);
Вот эти строки тоже жесть!
Почему не сделать SecondView окном?
Если SecondView работает только с SecondViewModel, то почему не создавать его в XAML SecondView?
Создаёте сами себе сложности на пустом месте.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,037
Записей в блоге: 2
24.08.2024, 11:40
IIIIIIIIIgor, интересно посмотреть код SecondView и SecondViewModel.
Очень сильные сомнения, что там что-то не так.

Будет хорошо, если целиком Решение загрузите на GitHub и дадите ссылку.
Если нет опыта работы с GitHub, то лучше сделать это через меню Git Студии.
Как это сделать - посмотрите здесь: Использование GitHub в Студии
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 254
26.08.2024, 16:05  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если SecondView работает только с SecondViewModel, то почему не создавать его в XAML SecondView?
что создавать в XAML? VM?

в данный момент нет возможности куда-либо выложить код.
если посоветуете какие-то книги/статьи/видео чтобы нормально разобраться во всем этом буду признателен
0
 Аватар для Andrey-MSK
3312 / 2199 / 387
Регистрация: 14.08.2018
Сообщений: 7,400
Записей в блоге: 4
26.08.2024, 16:17
wizard41, Ну по ссылке можно почитать и далее. Элд Хасп там предлагает вариант попроще

Добавлено через 3 минуты
wizard41, Ну и у меня в принципе не очень сложно. Просто нужно понять механизм DI, книг и статей по этой теме предостаточно. Тем более на готовом примере разобраться будет гораздо проще. Я эту информацию по кускам из разных статей и помощи товарищей набрал и собрал в одно целое. Теперь работает и просто таскаю из проекта в проект, ну и по мелочи что-то переделываю, по мере роста знаний
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,037
Записей в блоге: 2
26.08.2024, 17:40
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
что создавать в XAML? VM?
Да.
В самом простом случае:
XML
1
2
3
4
5
<SecondView ---------------------
            --------------------->
            <UserControl.DataContext>
                <vm:SecondViewModel/>
            </UserControl.DataContext>
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 254
23.09.2024, 15:46  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Пробуйте - Создание диалоговых окон, согласно паттерну MVVM
решил изучить предложенный вами подход, и не понимаю как происходит закрытие окна?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
internal class WindowService : IWindowService
    {
        private readonly IViewModelsService _viewModelsService;
 
        public WindowService(IViewModelsService viewModelsService)
        {
            _viewModelsService = viewModelsService;
        }
        public Window GetWindow(IBaseViewModel viewModel)
        {
            var window = _viewModelsService.GetWindow(viewModel);
 
            window.DataContext = viewModel;
 
            return window;
        }
 
        public void CloseWindow(IBaseViewModel viewModel)
            => GetWindow(viewModel).Close();
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class ViewModelsService : IViewModelsService
    {
        private readonly Dictionary<Type, Func<ContentControl>> _dict = new Dictionary<Type, Func<ContentControl>>();
 
        public IViewModelsService Register<TViewModelType, TViewType>()
            where TViewType : ContentControl, new()
            where TViewModelType : IBaseViewModel
        {
            _dict[typeof(TViewModelType)] = () => new TViewType();
 
            return this;
        }
 
        public Window GetWindow(IBaseViewModel viewModel)
        {
            var result = GetControl(viewModel);
 
            if (!(result is Window window))
                throw new Exception($"{result.GetType()} is not window");
 
            return window;
        }
 
        public ContentControl GetControl(IBaseViewModel viewModel)
        {
            var parentTypes = GetParentTypes(viewModel.GetType());
 
            foreach (var parentType in parentTypes)
            {
                if (_dict.TryGetValue(parentType, out var res))
                    return res();
            }
 
            throw new Exception($"ViewModel {viewModel.GetType().Name} is not registered");
        }
Тут же по сути при каждом обращении к WindowService идет обращение к ViewModelsService чтобы получить окно по указанной vm и он всякий раз создает новое окно. то есть получается из самой vm нельзя закрыть окно относящееся к ней?
такое
C#
1
_windowService.CloseWindow(this);
не срабатывает окно не закрывается. или я что-то упустил в вашем примере?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.09.2024, 15:46
Помогаю со студенческими работами здесь

Пример переключения между окнами WPF MVVM
Здравствуйте. Изучаю как можно переходить между окнами в wpf в рамках MVVM. Изучаю данный пример: ...

Передача данных между окнами в рамках паттерна MVVM
Доброго времени суток, уважаемые форумчане! Я абсолютный новичок в программировании, который пытается освоить, хотя бы в небольшой...

WPF MVVM + EFCore Передача данных между окнами
Всем привет! Столкнулся с проблемой при передачи/обновлении свойств между окнами. 1. Есть главное окно MainWindowViewModel.cs в...

Паттерн MVVM. Обмен данными между окнами с использованием ViewModels
Добрый день! Помогите, пожалуйста, понять тему насчет передачи данных в окошко с помощью ViewModel. Есть два окна MainView и LoginView,...

Работа с несколькими окнами одновременно
Необходимо чтобы 2 окна были открыты одновременно. сначала было согздана form1, затем я сделал form1.Hide(); form2.Show(); и дальше...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru