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

MVVM бизнес логика и Model

02.11.2021, 00:10. Показов 16210. Ответов 132
Метки mvvm (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Я уже довольно долго пытаюсь разобраться что же представляет из себя архитектура MVVM, конкретно задачи View и ViewModel мне понятны. Но остается вопрос что из себя представляет Model? Много где есть определение Model = бизнес логика. Но как понять какую логику отнести к модели, а какую например к сервису.
К сожалению толкового ответа я не нашел, может плохо гуглил. В уроках обычно банальные примеры с расселением студентов по комнатам, что редко отображает реальное использование программы. На YouTube смотрел уроки по созданию MVVM приложению от Павла Шмачилина(https://www.youtube.com/watch?... P4&t=3630s), но именно про архитектуру он рассказывает не настолько подробно как хотелось бы.
Все что я понял это то что Model занимается некими правилами записи и получения данных из сервисов. Также предоставляет данные для ViewModel. Тоесть та самая бизнес логика (про нее я смотрел https://www.youtube.com/watch?v=9DW-xdwjop8) и преобразование данных. Но уверенности что я все понял как нужно, нет.
Ниже приведены примеры с которыми я сталкивался, но понятного для меня решения не нашел.

Первый пример
Пример как я это вижу:
На View есть Listbox и Button, Listbox заполняется данными из ссылки на ObservableCollection во ViewModel, которая получает их из сервиса хранящего эти данные. Button при нажатии должна очистить Listbox и заполнить его новыми данными. Model имеет ссылку на ObservableCollection из сервиса и представляет из себя только один метод который будет очищать данные в ObservableCollection и сообщать сервису о том что их надо заново сформировать и добавить в ObservableCollection.

Тоесть:
Нажатие кнопки => ViewModel вызывает в модели команду очистить список и заполнить его => Модель очищает список и просит чтоб сервис его заполнил => В ObservableCollection к которой прибинжен Listbox срабатывает уведомление об изменении коллекции и Listbox загружает новые данные из нее.

Вопрос: Нужна ли тут модель? Или ее функции может выполнить Viewmodel? Конкретно очистить список и сообщить сервису чтоб он его заполнил.


Второй пример
Второй пример:
Есть View на которой расположен Listbox в котором находятся данные о мониторах которые подключены к компьютеру. Эти данные загружает в себя сервис при запуске приложения. ViewModel имеет ссылку на данные из сервиса, View занимается их отображение в ListBox. Задача Listbox состоит не только в отображении данных, но и чтоб при двойном клике по Item в Listbox мы например отключили/включили монитор и поменяли прозрачность его иконки в Listbox.

Тоесть:
Двойной клик по Item в Listbox => ViewModel посылает в Model команду на отключение выбранного из ObservableCollection монитора => Model устанавливает для монитора флаг Activated = false и меняет прозрачность иконки монитора на Listbox (сигнализируя пользователю что монитор отключен), после этого сообщают сервису чтобы он отключил монитор.

Вопрос: Должна ли Model сообщить сервису чтоб он отключил монитор или это должна сделать ViewModel? Или тут вообще нет необходимости в Model, так как ViewModel может сама выполнить эти действия? Может быть что то из этого можно вынести в логику View?


Третий пример
Третий пример:
У нас на View есть CheckBox который при нажатии на него добавляет некоторые параметры в реестр, есть ViewModel которая при нажатии на CheckBox посылает команду в модель о том что нужно добавить параметр в реестр и проверяет успешно ли этот параметр добавился.

Тоесть:
Нажатие на CheckBox => ViewModel посылает команду о добавлении параметра, Model пытается добавить параметр в реестр и если параметр успешно добавлен то возвращает true, если доабвить не удалось то возращает false => ViewModel проверяет успешно ли добавлен параметр в реестр и устанавливает для CheckBox свойство isChecked в зависимости от полученного результата.

Вопрос: Нужно ли тут использовать Model или для этого используется сервис? Если используется Model, то что она должна в себе содержать? Логику добавления параметров в реестр? Или Model должна обращаться к сервису который будет эту логику содержать и получать от него только результат который потом передаст ViewModel?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.11.2021, 00:10
Ответы с готовыми решениями:

Model в MVVM
Доброго времени суток. Начал изучать MVVM и даже что-то получается сделать, но не могу сообразить, что должно быть в Model? Программа...

MVVM Model
Здравствуйте, у меня возник вопрос что должно хранится в моделе, теорию прочитал, но на практике не понимаю. Конкретно в моем вариант...

MVVM. Общение Model с ViewModel
Занимаюсь проектом WPF, первый раз пробую MVVM-паттерн. Успешно реализовал общение View и ViewModel (бинды, команды), но никак не могу...

132
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
01.12.2021, 15:38  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это просто тестовая эмуляция изменения данных из других источников?
В реале её быть не должно?
В программе которую я делаю есть сервисы которые будут менять настройки мониторов в цикле. В основном три разных цветовых конфигурации которые представлены структурой. Тоесть каждую секунду проверяется какую цветовую конфигурацию требуется установить. Например время для запуска какой либо конфигурации задается из View, как и цветовая конфигурация, а сервис проверяет время(запущенные процессы, остаток цветового периода) и устанавливает нужную.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
01.12.2021, 20:10
Цитата Сообщение от xr_Sanya Посмотреть сообщение
В программе которую я делаю есть сервисы которые будут менять настройки мониторов в цикле.
Как они взаимодействуют с Моделью?
Может надо их просто включать-отключать, а не Модель им передавать?
То есть это часть БЛ Модели или отдельный от неё сервис?
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
02.12.2021, 04:53  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как они взаимодействуют с Моделью?
Может надо их просто включать-отключать, а не Модель им передавать?
То есть это часть БЛ Модели или отдельный от неё сервис?
Я сам не знаю чего они часть
Вот представьте есть у нас монитор. Пользователь задает время включения ночного режима и время включения дневного режима. Между ночным и дневным режимом программа ставит ночную гамму, между дневным и ночным дневную гамму.

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

Я доделал третию версию модели, посмотрите пожалуйста как будет время.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
02.12.2021, 13:13
Цитата Сообщение от xr_Sanya Посмотреть сообщение
доделал третию версию модели
Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
6
7
8
9
    internal partial class MonitorDomainCollection
    {
 
        // TODO: Нужны ли нам хендлеры в новой релизации?
Двояко.
В такой реализации - создавать и удалять Мониторы может только Основная Модель.
Но сами мониторы теперь тоже самостоятельные Модели.
Поэтому, в принципе, можно открыть конструктор и пусть их создаёт кто хочет.

Здесь вопрос больше в том, а как конструктор поместить в интерфейс?

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

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

Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
58
59
60
61
62
63
64
        /// <summary>
        /// Создает новую сущность
        /// </summary>
        /// <param name="monitorName"> имя создаваемой сущности </param>
        /// <returns><see cref="MonitorConfigurationDomainEntity"/></returns>
        internal MonitorConfigurationDomainEntity InternalAddMonitor(string monitorName)
            => MonitorsDomain.Add(monitorName) ? MonitorsDomain[monitorName] : null;
В этом методе сейчас нет необходимости.
Так как у нас сейчас есть публичный IMonitorConfigurationDomainEntity, то мы можем добавить в IMonitorModel метод bool AddMonitor(IMonitorConfigurationDomainEntity monitorDto);
или с параметрами для каждого свойства.
И уже используя публичный метод можно сразу добавить монитор с полным его состоянием, а не по одному свойству.

Добавлено через 6 минут
Немного не по самому коду.
Есть определённые правила и рекомендации по созданию тегов XML документации.
Это же не только всплывающие подсказки, но по ним можно создать и полную документацию проекта в виде справки.
Поэтому эти теги должны содержать законченные предложения.
В том числе текст в них должен заканчиваться точкой.
Добавлено через 52 минуты
xr_Sanya, внёс в Реп небольшие изменения.
Посмотрите их.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
02.12.2021, 17:00  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Двояко.
Мне тяжело представить ситуацию когда нужно создавать мониторы вне основной модели, ведь можно просто обращаться к основной модели для создания.
И в случае если создание и удаление мониторов подконтрольно только основной модели, то из модели монитора можно убрать все что относится к контролю ее состояния, тоесть хендлеры, методы OnPropertyChanged, Get, Create и поля IsAdded, IsDispose. Ведь подписчик всегда будет знать что модель уже удалена. По сути это похоже на первую релизацию, только тут уже по коду ходят модели мониторов а не DTO.

Добавлено через 9 минут
Цитата Сообщение от Элд Хасп Посмотреть сообщение
внёс в Реп небольшие изменения.
Посмотрите их.
Принято, буду стараться следовать рекомендации
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
02.12.2021, 18:09
Цитата Сообщение от xr_Sanya Посмотреть сообщение
По сути это похоже на первую релизацию, только тут уже по коду ходят модели мониторов а не DTO.
Скорее смесь первой и второй.
В первой реализации мы для изменения свойства Монитора обращались к методам Модели.

Во второй, "внутри" Модели у нас уже "гуляли" Мониторы и можно было работать непосредственно с ними не только через Модель, но и через какой-то сервис.
А для внешних потребителей параметры методов Модели максимально упростили.

Сейчас уже из Мониторов сделали самостоятельные Модели и они могут у нас спокойно и безопасно путешествовать по всему приложению.


Цитата Сообщение от xr_Sanya Посмотреть сообщение
Мне тяжело представить ситуацию когда нужно создавать мониторы вне основной модели, ведь можно просто обращаться к основной модели для создания.
Нужно, возможно, гарантированно ....
Это всё немного разная степень безопасности.
Когда есть возможность, то я предпочитаю делать "гарантированно".
Сейчас вам не нужно создавать, и вы не будете так делать.
А потом программу будет сопровождать кто-то другой и ему тоже это будет не нужно по логике, но он не будет знать что это нельзя делать, увидит, что это возможно и сделает.
А логика программы на это не рассчитана.
Хорошо ещё если просто вылетит исключение, а могут быть какие-то блуждающие, эфемерные баги, которые ещё и не отловишь.

Добавлено через 3 минуты
Цитата Сообщение от xr_Sanya Посмотреть сообщение
можно убрать OnPropertyChanged
А это почему можно убрать?
Как подписчик будет узнавать об изменении состояния свойств Монитора?
Только из-за реализации INPC мы и смогли превратить Мониторы в самостоятельные Модели.
Без этого это были бы Бизнес Сущности, которые должны быть инкапсулированы в Модели.

Добавлено через 11 минут
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Ведь подписчик всегда будет знать что модель уже удалена.
Здесь идёт только дублирование IsAdded и IsDispose.
В данном случае - это перестраховка и избыточно.
В реале же могут быть задачи где монитор это отражение (допустим) физического устройства, и когда монитор не нужен он должен освободить неуправляемые ресурсы.
После того как освободил Монитор становится не актуальным и к нему не следует обращаться, для этого и служит свойство IsDispose.
Но процесс освобождения ресурсов тоже не мгновенный.
Во время него обращения тоже могут быть некорректно.

Поэтому реализуется такой алгоритм:
- Перед началом освобождения ресурсов сбрасывается IsAdded;
- Все потребители по этому событию должны отключить актуализацию Монитора. Допустим, в WPF надо визуализировать коллекцию мониторов через CollectionView, а в нём будет фильтр по IsAdded;
- После того как все потребители отключили актуализацию, Монитор устанавливает свойство IsDispose и начинает освобождать ресурсы.
- Потребители по IsDispose=true удаляют у себя все ссылки на монитор, чтобы он мог отправиться в мусор.

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

Добавлено через 1 минуту
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Принято, буду стараться следовать рекомендации
Будут вопросы - задавайте.

Добавлено через 5 минут
Цитата Сообщение от xr_Sanya Посмотреть сообщение
методы OnPropertyChanged
А... понял о чём вы.
Да, это поддержка реализации IsDispose.
Сделана с демонстрационной целью.
В данном, конкретном случае она, конечно, не нужна.
Да, и самого начала она носила не практическую функцию, а демонстраннционную.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
04.12.2021, 01:38  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
вопросы
А как в последней реализации разрешить создание и удаление моделей мониторов только коллекции которая их содержит? Сейчас используется хендлеры, но мб есть другой способ?
Например я хочу чтобы создать модель монитора могла только модель которая непосредственно управляет ими, чтобы например никакая другая модель не могла это сделать напрямую, а только через метод основной модели?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
04.12.2021, 10:57
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Сейчас используется хендлеры, но мб есть другой способ?
1) Классы MonitorDomainCollection и MonitorConfigurationDomainEntity объявлены с модификаторам internal, поэтому доступны только внутри сборки (проекта) в котором они объявлены.
В этой сборке должны находиться только дружественные классы.
Другие недружественные модели, должны реализовываться в других сборках.
Поэтому можно переместить рандомайзер в другой проект, в этом оставить только MonitorModel.

2) Сейчас у нас есть интерфейс Мониторов, поэтому можно использовать его для сокрытия самой реализации.
Класс MonitorDomainCollection сделать приватным вложенным в MonitorModel.
Класс MonitorConfigurationDomainEntity сделать приватным вложенным в MonitorDomainCollection.
MonitorDomainCollection сделать производным от коллекции интерфейсов IReadOnlyDictionary<string, IMonitorConfigurationDomainEntity>.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
07.12.2021, 05:00  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
2) Сейчас у нас есть интерфейс Мониторов, поэтому можно использовать его для сокрытия самой реализации.
Класс MonitorDomainCollection сделать приватным вложенным в MonitorModel.
Класс MonitorConfigurationDomainEntity сделать приватным вложенным в MonitorDomainCollection.
MonitorDomainCollection сделать производным от коллекции интерфейсов IReadOnlyDictionary<string, IMonitorConfigurationDomainEntity>.
Сделал этот вариант, есть вопрос по IReadOnlyDictionary<string, IMonitorConfigurationDomainEntity>, интерфейс IReadOnlyDictionary просит метод IEnumerator<KeyValuePair<string, IMonitorConfigurationDomainEntity>> GetEnumerator(), но работаем мы с коллекцией которая этому не соответствует, я ее явно привожу к нужной. Не уверен что делаю правильно.
Реализация интерфейса в MonitorDomainCollection.IReadOnlyDiction ary.

Также добавил простую модель которая обновляет время для демонстрации, посмотрите пожалуйста насколько верно она добавлена.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
08.12.2021, 05:18  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Будут вопросы - задавайте.
Есть еще вопрос насчет BindingOperations.EnableCollectionSynchr onization, очень редко видел такое в коде, читал документацию майков, но слишком там заумно написано. Что это такое если вкратце и можно ли это чем то заменить в нашей реалзации?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
08.12.2021, 06:51
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Есть еще вопрос насчет BindingOperations.EnableCollectionSynchr onization
В WPF используется три основных события INotifyPropertyChanged.PropertyChanged, INotifyCollectionChanged.CollectionChanged, ICommand.CanExecuteChanged.

Все WPF элементы - это производные от DispatcherObject:
Комментарии
Только поток, на котором был создан Dispatcher объект, может напрямую обращаться к DispatcherObject . Для доступа к DispatcherObject из потока, отличного от потока, в котором был создан DispatcherObject, вызовите метод Invoke или BeginInvoke для Dispatcher связанного с DispatcherObject.
А что такое событие?
Это вызов методов по делегатам прикреплённым к событию.
И если это методы DispatcherObject (то есть любого WPF элемента), то вызов его метода выкинет исключение.
Поэтому все события, которые могут использовать WPF элементы должны подыматься в в основном UI потоке (за редким исключением все WPF элементы создаются в этом потоке).

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

Для событий CollectionChanged и CanExecuteChanged такого маршалинга в WPF нет.
В UWP есть марщалинг для CanExecuteChanged.
А в WPF приходится его встраивать в реализацию ICommand. Почему в WPF не сделано как в UWP.... Чёрт его знает.

С INPC коллекциями (в том числе ObservableCollection) всё несколько сложнее, так как кроме маршалинга события в UI поток нужно ещё обеспечить и потокобезопасность.
Потокобезопасность для коллекций обеспечивается (в простом случае) за счёт объекта синхронизации (локера).
В большинстве коллекций это ICollection.SyncRoot.
Об используемом локере надо сообщить механизму привязок в том потоке где будет привязываться коллекция.
Вот метод BindingOperations.EnableCollectionSynchronization и служит для этого.

Другой способ избежать исключений - это изменять INPC коллекцию всегда только в основном UI потоке.
Это тоже используется, но это довольно громоздко.
Каждый раз где надо добавить/удалить/заменить элемент придётся создавать лямбду и передавать её в Диспетчер UI потока.
И это значительно медленнее, так как выполнение отдельной задачи в довольно загруженном потоке происходит в порядке очерёдности и приоритетов.
Поэтому там где возможно (а это 99% практических задач) лучше использовать BindingOperations.EnableCollectionSynchronization.

Добавлено через 13 минут
Цитата Сообщение от xr_Sanya Посмотреть сообщение
BindingOperations.EnableCollectionSynchr onization, очень редко видел такое в коде
Наверное, потому, что большинство вопросов и ответов создаются начинающими.
Они пока не столкнутся с исключениями, вообще, мало об этом задумываются.
Если столкнутся, то почему-то для начинающих, вариант с использованием Диспетчера для изменения коллекции кажется проще.
Почему?.... Да чёрт его знает.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
08.12.2021, 07:10
Цитата Сообщение от xr_Sanya Посмотреть сообщение
вопрос по IReadOnlyDictionary<string, IMonitorConfigurationDomainEntity>, интерфейс IReadOnlyDictionary просит метод IEnumerator<KeyValuePair<string, IMonitorConfigurationDomainEntity>> GetEnumerator(), но работаем мы с коллекцией которая этому не соответствует, я ее явно привожу к нужной. Не уверен что делаю правильно.
Лучше внутренний словарь объявить для интерфейса:
C#
9
10
11
12
    internal partial class MonitorDomainCollection : BaseInpc
    {
        // Словарь где по именам хранятся Мониторы.
        private readonly Dictionary<string, IMonitorConfigurationDomainEntity> monitors = new();
Так же немного изменил объявление интерфейса монитора, чтобы для DTO не нужно было создавать не нужные члены:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.ComponentModel;
 
namespace Common.Interfaces
{
    public interface IMonitorConfiguration
    {
        double ColorConfiguration { get; set; }
        int Height { get; set; }
        bool IsActive { get; set; }
        string Name { get; }
        int Width { get; set; }
    }
    public interface IMonitorConfigurationDomainEntity : IMonitorConfiguration, INotifyPropertyChanged
    { }
}
Теперь по багам и нюансам:
1) Не реализована команда RefreshMonitors - выдаёт ошибку привязки.

2) В Модели есть два интерфейса:ICurrentTimeModel и IRandomizerModel. Для чего они там?
Интерфейс это способ описания публичного "лица" типа для того чтобы можно было не заботится о конкретной реализации типа.
И помещать интерфейс в той же сборке, что и его реализация... довольно бессмысленно.
Если у этих интерфейсов предполагается только по единственной реализации, то их просто надо удалить и предоставить саму реализацию.
Если же предполагается возможность создания разных реализаций, то их нужно вынести в отдельную библиотеку, в данном случае в Common.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
08.12.2021, 07:14
Изменения зафиксировал в 0ffdfc7c:
Исправлена реализация словаря в модели, разделено интерфейс Монитора, внесены сопутствующие правки.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.12.2021, 07:14

MVVM биндинг view в model
Я новичок, пытаюсь написать приложение UWP согласно паттерну MVVM В общем, в модели должен быть список экземпляров класса. В классе...

Бизнес-логика
Подскажите, как решить следующую проблему: Занимаюсь по пособию, и возникла ошибка. Код из C# public class DataCommands { ...

WPF MVVM - Transfer Data to Model
Всем привет, уважаемые. Есть два этапа: 1. Переношу коллекцию ObservableCollection из VM в Model. 2. А затем из Model в другую VM. ...

Каково назначение папки Model в MVVM
Просто я к тому, что все классы относящиеся к логике будут иметь пространство имён начинающееся с Model, это нормально вообще? Или не всю...

MVVM. Получение данных объекта по сети - в model или во viewmodel?
Здравствуйте! Вникаю в паттерн mvvm, прочитал\посмотрел кучу учебных материалов, и если честно, в голове каша уже. Мне понравился своей...


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

Или воспользуйтесь поиском по форуму:
133
Ответ Создать тему
Новые блоги и статьи
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru