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

Подскажите, пожалуйста, где в MVVM поместить экземпляр ViewModel, чтобы к нему имели доступ несколько View?

06.03.2015, 09:25. Показов 4640. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть Model.cs.
Есть ViewModel.cs. В ViewModel есть публичная коллекция Model и публичный метод AddNewModel (добавляет новую Model в коллекцию).
Есть MainWindowView.xaml и AddItemWindowView.xaml. В MainWindowView есть ListBox, к которому по ItemsSource привязана коллекция из экземпляра ViewModel. А в AddItemWindowView.xaml есть кнопка, к которой по Command привязан AddNewModel из того же экземпляра ViewModel.

Я разместил экземпляр ViewModel в классе App, сделал его публичным и из обоих View получаю к нему доступ через ((App)App.Current).viewModel.
Не нарушает ли это принципы MVVM? Есть лучшее решение?
Не стоит ли в данном случае отказаться от MVVM в пользу другого паттерна?
Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.03.2015, 09:25
Ответы с готовыми решениями:

Как правильно передать данные из View во ViewModel чтобы не нарушить шаблон MVVM
Здравствуйте. Вопрос такой есть View в него загружается html страница из интернета. И есть обработчик события который выполняется когда...

Паттерн MVVM. Взаимодействие ViewModel с View
Пишу приложение, используя паттерн mvvm. Есть солюшн, и в нем три проекта. %appname%View, %appname%ViewModel, %appname%Model. Ну и...

WPF MVVM View и ViewModel или UserControl и DependencyProperty
Не так давно ударился в WPF и шаблон MVVM. Вот такой вопрос возник... У меня есть View которая "собирается" из более мелких View....

11
Жуткая тВарЬ
394 / 329 / 135
Регистрация: 06.02.2015
Сообщений: 962
Записей в блоге: 1
06.03.2015, 18:45
А как взаимосвязаны две вьюшки? Они же сразу две не открываются при старте приложерия...а в целом в параметрах команд можно передовать, что угодно!
0
burning1ife
 Аватар для kenny69
1466 / 1287 / 294
Регистрация: 21.09.2008
Сообщений: 3,438
Записей в блоге: 9
06.03.2015, 20:44
Лучше сделать их взаимосвязь с помощью Messenger из MvvmLight:
При добавлении нового элемента отправлять сообщение для отображения окна добавления.
После редактирования нового объекта при сохранении отправлять сообщение, что произошло добавление и в viewmodel с коллекцией обрабатывать данное событие, предварительно подписавшись на него. Новый объект передается в параметрах сообщения.

Добавлено через 1 минуту
Таким образом наши viewmodel не знают ничего друг о друге, а лишь общаются через наш класс messenger, посылая в него сообщения и подписываясь на них.

В приложении набросал как я вижу.
Вложения
Тип файла: rar WpfMessenger.rar (1.89 Мб, 62 просмотров)
0
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 11
06.03.2015, 21:45  [ТС]
amarf, возможно по-всякому. Main может открывать AddItem по кнопке, AddItem может являться контролом в Main... Я их как пример привел.

Добавлено через 20 минут
kenny69, MvvmLight мне не очень нравится тем, что делает код непонятным неподготовленному человеку и загромождает его. Это впечатление по Вашему примеру.
Нельзя как-то проще, чтобы только Messager оттуда, а остальное стандартное и без наворотов? Спасибо.

Добавлено через 6 минут
Возможно, мне стоит показать конкретный код.
Main View XAML
Main View Code-Behind
Add Item View XAML
Add Item View Code_Behind
ViewModel

Это только мне так кажется, или это все-таки читабельнее, чем ваш пример, хоть там и больше всяких разных методов-кнопочек?
0
Жуткая тВарЬ
394 / 329 / 135
Регистрация: 06.02.2015
Сообщений: 962
Записей в блоге: 1
06.03.2015, 21:52
Jur, Если контрол открывается через мэйн, то предавайте команду или сам мейн в параметре команды, которой открываете вьюшку.
Если вьюшка контрол в мейне, то просто общайтесь с этой командой через байдинг и датаконтекст, он по дереву вверх нормально присоединиться
1
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
06.03.2015, 22:06
Цитата Сообщение от Jur Посмотреть сообщение
kenny69, MvvmLight мне не очень нравится тем, что делает код непонятным неподготовленному человеку и загромождает его.
Возможно это и так, пока у тебя проект с 2-мя окнами (ну лады, с 5-ю) и ты точно знаешь, что и как будет в итоге и вряд ли нужно будет что-то сильно менять. Но если программа будет большая, сильно сомневаюсь, что получится сохранить всё максимально читабельно для неподготовленного человека. А проект, что тебе скинули, я посмотрел, вообще всё мега просто и понятно. Там абсолютно ничего сложного нет.

Добавлено через 1 минуту
Цитата Сообщение от Jur Посмотреть сообщение
Это только мне так кажется, или это все-таки читабельнее, чем ваш пример, хоть там и больше всяких разных методов-кнопочек?
На самом деле нечитабельно кажется, пока не засядешь и не разберёшься. Далее всё предельно читабельно становится.

Добавлено через 48 секунд
Ссылки только у меня не открываются в Опере и Хроме?

Добавлено через 10 минут
Слушай, а ты скинь свой проект и на его примере можно попробовать показать разные способы того, что тебе нужно. А то по своему сделаешь, а тебе не так покажется. А время просто так не охота тратить.
0
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 11
06.03.2015, 22:12  [ТС]
Casper-SC, а есть какая-нибудь IDE с шаблонами MvvmLight, чтобы не писать все это ручками?

Ссылки только у меня не открываются в Опере и Хроме?
У меня тоже. Firefox. Должно быть, дело в хештеге.
Вот эта ссылка должна открываться: https://xpomxpum.codeplex.com/SourceControl/latest
Под Main я имел ввиду IntegratorSettingsWindowView.cs, под AddItem - AddBrowserWindowView.cs, а под ViewModel - IntegratorSettingsWindowViewModel.cs.

Добавлено через 2 минуты
Заходите подряд в 2 папки с длинными названиями, начинающихся на "Xpom-Xpum", затем за вьюшками в View, за моделью - в ViewModel.
0
burning1ife
 Аватар для kenny69
1466 / 1287 / 294
Регистрация: 21.09.2008
Сообщений: 3,438
Записей в блоге: 9
06.03.2015, 22:33
Цитата Сообщение от Jur Посмотреть сообщение
MvvmLight мне не очень нравится тем, что делает код непонятным неподготовленному человеку и загромождает его. Это впечатление по Вашему примеру.
Может быть только первый взгляд такой, смысл простой: подписались на сообщения в одном месте, отправили сообщение в другом месте. Все мега просто, и все компоненты слабо связаны.

Добавлено через 2 минуты
Да и не обязательно все использовать из MvvmLight, тот же Locator и SimpleIoC можно заменить другими или вообще не использовать.

Добавлено через 1 минуту
Цитата Сообщение от Jur Посмотреть сообщение
загромождает его
может наоборот?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
08.03.2015, 00:36
Цитата Сообщение от Jur Посмотреть сообщение
Casper-SC, а есть какая-нибудь IDE с шаблонами MvvmLight, чтобы не писать все это ручками?
Просто через .NuGet подключи MvvmLight, там всё само создастся.

Добавлено через 8 минут
Посмотрел твой проект. Поставь себе XAML Styler через "Сервис" - "Расширения и обновления", в настройках его поставь, а то не представляю как ты читаешь XAML код в таком формате:
Ordered attributes by name = True
Beautify on saving xaml = False
Reorder Grid panel children by row/column = False <<<= Если тру, то иногда может накосячить в плане того, что по задумке должно быть сверху какого-то другого элемента, если, к примеру в Grid вложено много элементов и какой над каким ты определили порядком их следования в XAML.

Добавлено через 8 минут
Посмотрел как ты сохраняешь объект при нажатии на кнопку ОК. Да думаю, тоже вполне нормальный вариант. По крайней мере не вижу особых минусов передачи объекта в другую вью модель таким способом.
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
08.03.2015, 01:02
Устанавливаешь библиотеки:


Потом настраиваешь App.xaml, иногда чёто может глюкануть и автоматом оно не настраивается, хотя должно. К примеру, когда я писал этот пример, то мне вылезло сообщение, что App.xaml не найден.

Про App.xaml.cs можешь забыть, придётся всё прописывать в ViewModelLocator или другом классе, который будет вызывать в конструкторе ViewModelLocator. По крайней мере в App.xaml.cs у меня не срабатывает ни одно событие. Но это вообще не беда, думаю.

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Application x:Class="MvvmExample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:viewModel="clr-namespace:MvvmExample.ViewModel"
             StartupUri="Views\IntegratorSettingsWindowView.xaml"
             d1p1:Ignorable="d">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!--<ResourceDictionary Source="pack://application:,,,/XXX.Controls;component/Resources/Skins/Main.xaml" />-->
            </ResourceDictionary.MergedDictionaries>
 
            <viewModel:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
 
        </ResourceDictionary>
 
    </Application.Resources>
</Application>
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
08.03.2015, 03:18
Я, конечно, догадываюсь, что найдутся те, кто скажет: -Ой, так много кода геморного, какие-то Window Services и т.д. А как по мне, так самый норм вариант. Благодаря этим сервисам можно тестировать код в юнит тестах подставляя вместо реальных сервисов с окнами фейки. Например можно юзать Moq для этих целей. Как юзать пример тут: http://professorweb.ru/my/ASP_... l2/2_5.php

Я сделал на основе твоего примера. Просто взял из твоего проекта окна и сделал то что тебе нужно.

Часть кода:
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
36
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using MvvmExample.WindowService;
 
namespace MvvmExample.ViewModel
{
    //Это тот самый Composition Root (гугли)
 
    public class ViewModelLocator
    {
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
 
            SimpleIoc.Default.Register<IBrowserWindowService, BrowserWindowService>();
            SimpleIoc.Default.Register<IIntegratorWindowsService, IntegratorWindowService>();
            SimpleIoc.Default.Register<IntegratorSettingsViewModel>();
            SimpleIoc.Default.Register<MainViewModel>();
        }
 
        //Не стоит помещать все возможные вью модели сюда таким способом. Остальные, к примеру, 
        //может создавать эта вью модель в своих методах, когда нужно.
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
        
        public static void Cleanup()
        {
            // TODO Clear the ViewModels
        }
    }
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using MvvmExample.WindowService;
 
namespace MvvmExample.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private readonly IIntegratorWindowsService _integratorService;
        private readonly IntegratorSettingsViewModel _integrator;
 
        private RelayCommand _onLoaded;
        private RelayCommand _runSettings;
 
        //Параметр подставится автоматом, так как он зарегистрирован во ViewModelLocator
        //SimpleIoc.Default.Register<IWindowsService, WindowService>();
        //Передача сюда сервиса через интерфейс это принцип инверсии управления (Inversion of Control)
        public MainViewModel(IIntegratorWindowsService integratorService, IntegratorSettingsViewModel integrator)
        {
            _integratorService = integratorService;
            _integrator = integrator;
        }
 
        public RelayCommand OnLoadedCommand
        {
            get
            {
                return _onLoaded ?? (_onLoaded = new RelayCommand(() =>
                    {
                        WindowManager.Instance.Initialize(Application.Current.MainWindow, this);
                    }));
            }
        }
 
        public RelayCommand RunSettingsCommand
        {
            get
            {
                return _runSettings ?? (_runSettings = new RelayCommand(() =>
                {
                    _integratorService.OpenRunSettingsDialog(_integrator, this);
                }));
            }
        }
    }
}
Вложения
Тип файла: rar MvvmExample.rar (28.8 Кб, 15 просмотров)
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
08.03.2015, 03:27
Как можно прикрутить сплэш скрин тоже могу показать на основе этого примера. Я как-то убил день, всё испробовал, вроде как нашёл более-менее нормальный способ.

Добавлено через 3 минуты
Если не понятно, что за ServiceLocator и зачем нужен, то смотри:


И читай: IoC, DI, IoC-контейнер — Просто о простом

Добавлено через 4 минуты
С Messenger вместо IWindowService тоже вариант, но меня там напрягает поиск реализации этих сообщений, так как никаких ссылок в коде нет. А так навигация по методам интерфейсов и быстро находишь что откуда и куда.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.03.2015, 03:27
Помогаю со студенческими работами здесь

Как обновить View при изменении свойства в ViewModel MVVM
View: &lt;DataGrid Grid.Row=&quot;0&quot; ItemsSource=&quot;{Binding SaleItemData}&quot; AutoGenerateColumns=&quot;False&quot; CanUserAddRows=&quot;False&quot;&gt; ...

Доступ к свойствам из другой ViewModel [MVVM Light]
Здравствуйте! Как получить доступ к свойствам одной ViewModel из другой ViewModel? Использую MVVM Light. Долго гуглил, нашел, что нужно...

Где объявить sqlConnection, чтобы к нему был доступ из разных методов
Здравствуйте. в своем классе я обьявляю переменную SqlConnection myConnection; для того чтоб потом это соединение можно было использовать...

Доступ к View без нарушения правил MVVM
Здравствуйте, дорогие форумчане. Я недавно начал изучать MVVM. Вот недавно столкнулся с одной проблемой: как мне , допустим, создать...

Как обозначить глобальные переменные, чтобы оба файла .c имели к ним доступ
Имеется файл с расширением .h. В нем указаны глобальные переменные(например int n=0), так же в этом файле есть прототип функции, который...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
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 . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru