Форум программистов, компьютерный форум, киберфорум
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. Показов 16240. Ответов 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
15.11.2021, 01:03  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Поэтому Модель должна для изменения вызывать метод сущности, а сущность через событие уведомлять об изменении свойства (вот здесь может прекрасно подойти INPC).
Тоесть в MonitorConfigurationDomainEntity я реализую INPC, при изменении полей сущности он должен уведомить модель? А модель уже с помощью Event уведомить ViewModel об изменении?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
15.11.2021, 01:38
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Тоесть в MonitorConfigurationDomainEntity я реализую INPC, при изменении полей сущности он должен уведомить модель? А модель уже с помощью Event уведомить ViewModel об изменении?
Да.
Тогда это уже будут полноценные Domain Entity.

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

INPC или другое событие....
Можно сделать две реализации, чтобы на практике увидеть как проще в этом случае (на вскидку - INPC будет проще), и чтобы вы в будущем знали о возможных вариантах и могли осознано выбирать лучший для конкретной задачи.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
15.11.2021, 01:48  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Domain Entity
А как правильно подписать модель на изменения конкретной сущности? Ведь INPC только то что свойство изменилось уведомит, а в где оно изменилось неизвестно.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
15.11.2021, 02:36
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Ведь INPC только то что свойство изменилось уведомит, а в где оно изменилось неизвестно.
Ну....
Вы сигнатуру события посмотрите.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
15.11.2021, 05:43  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ну....
Вроде сделал и даже работает, насколько криво судить вам
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
15.11.2021, 11:15
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Вроде сделал и даже работает, насколько криво судить вам
Там несколько сложнее.
Помните я вам писал (если не ошибаюсь), что для начинающих лучше проектировать приложение с Модели.
Вот здесь будет пример того почему вроде несущественные изменения в БЛ приводят к изменению почти всей архитектуры приложения.

Давайте не будем торопиться, откатимся на рабочую фиксацию с прошлой архитектурой 9adf03e1 - можете зафиксировать её в отдельной ветке.

Под новую архитектуру тоже можно создать новую ветку.
Начнём сначала с теоретических предпосылок.

Мы хотим реализовать полноценные сущности, которые могут спокойной передаваться по всей БЛ.
НО! Есть две функции которые должны остаться только за Моделью - это создание и уничтожение этих сущностей.
Делегировать эти функции можно специально созданной нами коллекции MonitorDomainCollection.
Она сейчас реализует интерфейс IDictionary<>, а нужно переделать на IReadOnlyDictionary<>.
И добавить в него методы для создания и удаления сущности по имени.
А значит и подписку на событие каждой сущности лучше делать в этой коллекции и в ней добавить событие уже с аргументом показывающем имя изменившейся модели, название изменившегося свойства и новое значение свойства.

Второе, удалённая/добавленная/уничтоженная сущность должна извещать об этих своих состояниях, но у нас нет соответствующих свойств.
Значит нужно добавить свойства (названия на усмотрение) IsAdded (или IsLoaded) и IsDispose.
Логика такая:
Добавление:
1) Модель вызывает метод коллекции Add(string name). Метод возвращает false или исключение, если с таким именем нельзя добавить;
2) Если всё Ок, то Коллекция создаёт сущность, подписывается на её событие и добавляет во внутренний словарь;
3) После добавления Коллекция меняет у сущности IsAdded = true;
4) Сущность изменила значение свойства, генерируется событие об этом, это событие генерирует событие коллекции, а то генерирует событие Модели;
5) Слушатель Модели получает событие о создании нового объекта. Генерирует его его отражение и добавляет в свою коллекцию.

Удаление:
1) Модель вызывает метод коллекции Remove(string name). Метод возвращает false или исключение, если с таким именем нельзя удалить;
2) Коллекция вызывает метод удаления сущности, который доступен только ей. А как такой метод реализовать?;
3) Сущность меняет значение IsAdded = false;
4) Сущность изменила значение свойства, генерируется событие об этом. Коллекция по этому событию удаляет сущность из своего словаря и генерирует своё событие;
5) После завершения этого события, сущность уже изменяет IsDispose = true. После этого, обращение к любому другому свойству должно выкидывать исключение "Объект уничтожен". Об изменении IsDispose создаётся своя цепочка событий;


А теперь вдумайтесь, что существенного изменится из=за такой логики?

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

Потребители Модели должны сами реализовать объекты отражающие сущности Бизнес Логики.
Для VM это могут быть мутабельнные типы.

Обдумайте всё это.
Если для вас путано, то я сам начну такую реализацию.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
16.11.2021, 02:08  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Обдумайте всё это.
Да, звучит хорошо, насколько я понимаю например можно будет менять DomainEntity прямо из View через двустороннюю привязку.

В последнем коммите попытался реализовать подобную архитектуру исходя их моих знаний, пометил TODO что добавлял
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
16.11.2021, 13:04
Цитата Сообщение от xr_Sanya Посмотреть сообщение
насколько я понимаю например можно будет менять DomainEntity прямо из View через двустороннюю привязку
Не в View, а в VM, и то только частично.
Создавать и удалять их по прежнему может только Модель.
Да, и в общем случае лучше в VM реализовать своё отражение.
Это в этой задаче у вас Представляются непосредственно DomainEntity.
А так может быть у DomainEntity очень много свойств и методов которые не нужны на уровне View и могут быть неправильно использованы.
Может быть, напротив, нужны какие-то доп. свойства, которых у DomainEntity нет.
Ну, и др.
Поэтому доменные сущности (Бизнес сущности) лучше выше уровня Модели не выпускать.
Но на уровне Модели они могут путешествовать как угодно.
Самый типичный пример - это использование их в Репозитории.

Цитата Сообщение от xr_Sanya Посмотреть сообщение
В последнем коммите попытался реализовать подобную архитектуру исходя их моих знаний, пометил TODO что добавлял
Посмотрю, но может не сразу.

Добавлено через 57 минут
Сделал Фиксацию 1781c8b3:
Реализованы Бизнес-сущности с приватным конструктором и проверкой удаления объекта при обращении к его свойствам. Добавлена фабрика, возвращающая экземпляр и метод для добавления и удаления объекта.
Добавлено через 1 час 7 минут
Сделал Фиксацию e88ae3b7:
Реализована коллекция Мониторов.
Пока посмотрите это.
Лишние TODO (те что уже прояснены) - удалите.

Добавлено через 32 минуты
Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
18
19
        // TODO: Можно ли тут использовать dynamic?, слышал что не очень хорошая практика
        public object Value { get; }
Наверное, можно в каких-то случая, но конкретно в этом - зачем?

dynamic используется для доступа к членам объекта, которые неизвестны на момент компиляции.
А здесь какие члены Value вы хотите использовать?

Добавлено через 1 минуту
P.S. Обратите внимание на изменение аргумента события BaseInpc.PropertyChanged в методе RaisePropertyChanged.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
16.11.2021, 20:51  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А здесь какие члены Value вы хотите использовать?
Думал что можно использовать это вместо того чтобы каждый раз приводить объект к нужному типу)

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Пока посмотрите это.
Все ок, вопросов нет, хенделер только не совсем понятно зачем использовать
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
16.11.2021, 23:25
Цитата Сообщение от xr_Sanya Посмотреть сообщение
хенделер только не совсем понятно зачем использовать
Чтобы метод добавления и удаления мог вызвать только создатель сущности.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
17.11.2021, 09:36
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Все ок, вопросов нет,
Ок!

Теперь нужно изменить интерфейс Модели с учётом того, что нет DTO.

Public методы Модели могут отдавать только общедоступные типы (string, object, int и т.д.).
Internаl методы могут отдавать и сами сущности - они могут использоваться в сервисах уровня Модели.

Попробуйте это реализовать.

Добавлено через 1 минуту
В интерфейсе Модели должны быть только Public члены.
Intenal будут реализованы, но в интерфейсе их не должно быть.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
17.11.2021, 14:01  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Теперь нужно изменить интерфейс Модели с учётом того, что нет DTO.
Вроде как сделал, все вопросы помечены TODO

Цитата Сообщение от Элд Хасп Посмотреть сообщение
В интерфейсе Модели должны быть только Public члены.
Intenal будут реализованы, но в интерфейсе их не должно быть.
С интернал вышла заминочка, ведь сервис который работает с моделью нужно передать интерфейс модели, а в нем не может быть интернал метода который должен выдавать сущность
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
17.11.2021, 15:02
Цитата Сообщение от xr_Sanya Посмотреть сообщение
С интернал вышла заминочка, ведь сервис который работает с моделью нужно передать интерфейс модели
Смотря, что за сервис.
Ведь сами Бизнес сущности - это тоже internal типы.
Если он будет работать непосредственно с Бизнес сущностями, то он долен быть дружественным в Модели, то есть реализован в той же сборке или в дружественной сборке.

Если же это внешний (по отношению у Модели) сервис, то тогда, конечно, он может работать только с public типами и членами.

Добавлено через 39 минут
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Вроде как сделал, все вопросы помечены TODO
Сначала по интерфейсу:
Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
31
32
33
        /// <summary>Создает новый монитор.</summary>
        /// <param name="monitor">Отражение сущности</param>
        bool AddMonitor(MonitorConfiguration monitor);
Одна из целей этой реализации - постараться сделать её без промежуточных DTO.
Поэтому стоит тип MonitorConfiguration исключить из реализации.

Логика создания нового монитора из GUI должна быть такой:
1) Запрашиваем создание монитора с указанным именем;
2) Ловим событие о его добавлении и создаём внутри VM сущность отражающую его. Эта сущность не обязательно полное отражение Бизнес Сущности. Да, VM и не знает о конфигурации Бизнес Сущностей. Здесь может быть только часть свойств и/или дополнительные свойства, может быть реализация INPC и др.;
3) По одному свойству запрашивает в Модели изменение Бизнес сущностей и по событиям Модели изменяет свойства своего отражения.

Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
52
53
54
55
56
57
        public bool IsDispose
        {
            // TODO: ошибка _isDispose должен быть вместо _isAdded
            get => Get(_isDispose);
            private set => Set(ref _isDispose, value);
        }
Да - это была описка.
И даже больше.
IsDispose - можно запрашивать после удаления.
Поэтому нужна обычная реализация:
C#
52
53
54
55
56
        public bool IsDispose
        {
            get => _isDispose;
            private set => Set(ref _isDispose, value);
        }
Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
81
82
83
84
85
86
87
        protected T Get<T>(in T propertyField, [CallerMemberName] string propertyName = null)
        {
            // TODO: StackOverflow ex (IsDispose && propertyName != nameof(IsDispose))
            return propertyName != nameof(IsDispose) && IsDispose
                ? throw new ObjectDisposedException("Монитор уже удалён.", Name)
                : propertyField;
        }
Это ошибка была из-за неправильной реализации геттера свойства IsDispose.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
C#
50
51
            // TODO: Не понятно как создать сущность сразу с готовыми параметрами без изменения метода коллекции
            if (!MonitorsDomain.TryGetValue(monitor.Name, out var monitorEntity)) return false;
Выше ответил.
Сразу сущность создаваться не будет.
Сначала создание по имени, потом изменение по одному свойству.

Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
11
12
13
14
15
16
17
18
19
20
21
22
    public partial class MonitorModel
    {
        private static MonitorConfiguration Create(MonitorConfigurationDomainEntity monitor)
            => new MonitorConfiguration(
                monitor.Name,
                monitor.Height,
                monitor.Width,
                monitor.IsActive,
                monitor.ColorConfiguration
            );
 
        // TODO: создать мы сами сущность не можем
Все эти методы (Create, Copy) в данной реализации не нужны.

Цитата Сообщение от xr_Sanya Посмотреть сообщение
C#
48
49
50
51
52
53
54
55
56
57
        protected override void OnPropertyChanged(in string propertyName, in object oldValue, in object newValue)
        {
            base.OnPropertyChanged(propertyName, oldValue, newValue);
 
            if (propertyName == nameof(RandomizerState))
            {
                if ((bool)newValue)
                {
                    // TODO: тут мы должны передать модель для работы с сервисом?
                    //randomizerModel.Start(monitorModel);
Нет.
В VM нет Бизнес сущностей (Мониторов) поэтому она не может их передать.
Если ей надо обратиться к стороннему Сервису, она просто указывает имя Монитора.

А уже сам Сервис будет определять как ему работать с Моделью.
Если он дружественный к Модели, то он может получить от неё Монитор и работать сам с Бизнес Сущностью.
Если он сторонний к Модели, то работает с ней через публичный интерфейс.

Добавлено через 2 минуты
P.S. xr_Sanya, в такой как у нас сейчас реализации Мониторов, можно их сделать и публичными - по сути это полноценные Модели.
Но давайте сделаем реализацию сначала с инкапсулированными Бизнес Сущностями.
А потом следующую реализацию - сделаем их публичными.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
17.11.2021, 16:00  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ловим событие о его добавлении
Для этого нужен отдельный Event? Ведь у нас только есть о изменении свойств
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
17.11.2021, 19:34
Цитата Сообщение от xr_Sanya Посмотреть сообщение
Для этого нужен отдельный Event? Ведь у нас только есть о изменении свойств
Этого же достаточно.
Мы ловим IsAdded=true - по этому событию создаём отражающую сущность.
По IsAdded=false - производим какие-то действия (если нужно) перед её удалением.
По IsDispose=true - удаляем отражающую сущность.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
21.11.2021, 03:25  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Этого же достаточно.
Попытался все реализовать, но в итоге получил много вопросов которые пометил TODO)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
21.11.2021, 10:13
Цитата Сообщение от xr_Sanya Посмотреть сообщение
пометил TODO
C#
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
49
50
            // Это часть Модели (дружественна ей), поэтому может работать  непосредственно с ней
            public static void LoadMonitors(MonitorModel model)
            {
                // Здесь чтение из файла и формирование списка.
                // Мониторы должны иметь уникальные имена
                // TODO: нужен какойто новый способ инициализации мониторов
                //HashSet<MonitorConfigurationDomainEntity> monitors = new(MonitorEqualityComparer.Instance);
 
                MonitorConfigurationDomainEntity monitor = model.InternalAddMonitor("Monitor 1");
                if (monitor != null)
                {
                    monitor.Height = 1000;
                    monitor.Width = 1000;
                    monitor.IsActive = true;
                    monitor.ColorConfiguration = 6600;
                }
                monitor = model.InternalAddMonitor("Monitor 2");
                if (monitor != null)
                {
                    monitor.Height = 2000;
                    monitor.Width = 2000;
                    monitor.IsActive = true;
                    monitor.ColorConfiguration = 5500;
                }
                monitor = model.InternalAddMonitor("Monitor 3");
                if (monitor != null)
                {
                    monitor.Height = 3000;
                    monitor.Width = 3000;
                    monitor.IsActive = false;
                    monitor.ColorConfiguration = 7000;
                }
 
                // Возврат сформированного списка
                // return monitors;
            }
C#
56
57
58
59
60
61
62
63
64
                // TODO получить данные для монитора невозможно, если только индексаторы в модели делать
                // В Модели можно добавить internal метод возвращающий все Бизнес сущности
                foreach (var monitor in monitorModel.GetMonitors())
                {
                    // Здесь рабтаем с Бизнес сущностями monitor
                }
 
                // Цикл по именам не нужен
                foreach (var monitorName in monitorModel.GetMonitorNames())
C#
7
8
9
10
11
12
    public partial class MainWindowViewModel : ViewModelBase
    {
        // TODO Что должна хранить в нашем случае коллекция? Отражения или имена мониторов?
        // Отражения.
        // В данном случае это будет почти такая же реализация как и защищённые Бизнес Сущности.
        public ObservableCollection<MonitorVM> Monitors { get;} = new();
C#
69
70
            //    // TODO: так как метода получения данных из модели теперь у нас нет, то как обновлять данные выбранного монитора?
            //       Выбранный монитор обновлять не надо. Все отражения (в том числе и выбранный монитор) обновляются по событию Модели
Фиксация 6f439e0a:
Ответы на TODO и частичное продолжение реализации.
0
3 / 3 / 0
Регистрация: 13.07.2020
Сообщений: 229
21.11.2021, 22:56  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ответы на TODO и частичное продолжение реализации.
Попытался восстановить работу, но есть проблемы с инициализацией сущностей и c RandomizerModel. Так и не понял из за чего, RandomizerModel обращается к уже удаленным мониторам.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
22.11.2021, 00:09
xr_Sanya, посмотрю, но наверное, не раньше вторника.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
23.11.2021, 18:42
xr_Sanya, Фиксация 3532c2c2:
Фикс всех выявленных багов. Получена рабочая версия.
Добавлено через 24 минуты
И другой способ Фиксация c697566c:
Реализация извещения нового подписчика обо всех мониторах.
Добавлено через 1 минуту
Поудаляйте лишнее, посмотрите может ещё что-то не работает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.11.2021, 18:42

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, прочитал\посмотрел кучу учебных материалов, и если честно, в голове каша уже. Мне понравился своей...


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
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
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru