|
Модератор
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
INPC (INotifyPropertyChanged) и получение данных из Модели [WPF, Элд Хасп]27.01.2019, 17:51. Показов 23765. Ответов 63
Метки c, incc, inotifypropertychanged, inpc, model, model-view-viewmodel, mv, mvvm, view, viewmodel, vm (Все метки)
Сообщение было отмечено Элд Хасп как решение
Решение
Тема из цикла Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]
MVVM состоит из трёх раздельных частей. "Знания" этих частей друг о другу ограничены. View знает только о VM, VM только Model, а Model знать никого не желает. В такой схеме передача данных от View в Model проблем не вызывает. Ограничения есть только для передачи данных от View к VM. Для отправки данных View обращается к Set методу нужного свойства VM (к которому осуществлена привязка), поэтому привязывать свойства View можно только к публичным свойствам VM. Привязать к полям или методам VM невозможно. Если взять VM из примера в WPF команды и MVVM. Часть 1. пост#15, то свойства First, Second можно упростить до автосвойств и на функционировании приложения это ни как не скажется (сброс свойства Result в данном случае можно опустить)
Но как определить View, что данные изменились и их надо заново запросить? Для этого VM должна известить View о том какие данные были изменены. Это извещение (событие) для WPF View должно происходить через реализацию интерфейсов INotifyPropertyChanged (INPC) для свойств и INotifyCollectionChanged (INCC) для коллекций (здесь рассматривать не буду). Дефолтная реализация реализация интерфейса INPC состоит всего из одной строчки
OnPropertyChanged() равносильно OnPropertyChanged("Result")Но только такое использование INPC необязательно. Можно заменить Result на автосвойство и вызывать OnPropertyChanged при записи в него нового значения.
В VM при изменении значений свойств First, Second и SelectOperator будем отправлять в View сообщение об изменении свойства Result. А в свойстве Result пропишем обращение к свойствам Модели
Если для отправки извещения в View, VM должна реализовывать INPC или INCC, то модель этим не ограничена. Но использование этих интерфейсов в большинстве случаев удобно и позволяет сделать код более прозрачным и читаемым. Можно использовать INPC не совсем стандартно. По своей сути событие PropertyChanged пересылает просто текстовое сообщение (string), ни каких проверок на существование свойства с таким именем не производится. Поэтому не обязательно чтобы параметр метода OnPropertyChanged был названием свойства. В примере выше, VM обращается к методам Модели сразу возвращающим данные, но такие методы не всегда есть у модели. И если значения свойств First, Second и SelectOperator сразу посылать в Модель, то VM не может знать изменится Result или нет. Для этого при изменении Result Модель должна создать событие извещающее об этом, а VM "прослушивать" это событие и по нему запросить данные. Пример Модели. В Модели реализованы методы для получения данных от VM: First, Second и SelectOperator. Методы для возвращения данных в VM: GetResult и GetOperators. Для удобства введён дополнительный конструктор сразу подключающий "прослушку" события PropertyChanged. Имена методов Модели намеренно сделаны не совпадающими с именами свойств VM для большей наглядности взаимодействия. Для этой же цели PropertyChanged сообщает VM об изменении несуществующего свойства ResultChange
Инициализация Модели сделана через обращение к свойству для подключения прослушки чтобы не создавать конструктор ViewModel. В методе Model_PropertyChanged прослушивающем PropertyChanged проверяется имя свойства, если оно ResultChange, то отправляется извещение в View об изменении свойства Result. Пр обращении View к свойству Result оно получает своё значение от модели.
Кликните здесь для просмотра всего текста
Теперь к такой Модели можно подключить другие View и ViewModel Модель и первые View+VM почти те же. Добавлена только возможность ссылки на модель через статическое поле. Добавление в Модели
Кликните здесь для просмотра всего текста
Модель
Кликните здесь для просмотра всего текста
Кликните здесь для просмотра всего текста
Кликните здесь для просмотра всего текста
Во второй цепочке "Result" используется упрощённая VM и выводится только результат.
10
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 27.01.2019, 17:51 | |
|
Ответы с готовыми решениями:
63
Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп]
Передача данных между Окнами, между VM, Шина Сообщений, Локатор [WPF, Элд Хасп] |
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||||||
| 27.01.2019, 18:57 | ||||||||
null или string.Empty уведомляет о том, что изменились все свойства объекта.Порой бывает удобно уведомить интерфейс чтобы он обновил биндинги на всех свойствах — например, при реализации транзакций или обертки над моделью, где свойства — всего лишь обертка над вложенным объектом и этот объект поменялся на другой. Из-за часто используемой реализации INPC с атрибутом CallerMemberName с этим могут возникнуть проблемы, т.к. передаваемое имя свойства автоматом подменяется на имя вызывающего метода. Если планируется уведомлять интерфейс об изменении всех свойств, то метод можно малость изменить/расширить:
5
|
||||||||
|
Модератор
|
|||
| 27.01.2019, 19:24 [ТС] | |||
|
Но в аспекте [CallerMemberName]string propertyName="" и использование в качестве имени свойства null... не будет такого же результата с OnPropertyChanged(null)?
0
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 27.01.2019, 20:09 | ||
|
Возможно, в поздних версиях фреймворка это пофиксили.
0
|
||
|
Модератор
|
||
| 27.01.2019, 20:23 [ТС] | ||
() замещает названием метода, при (null) остаётся null.На обновление всех свойств не проверял. Но одно свойство обновляет нормаль - я в примере заменил OnPropertyChanged("Result"); на OnPropertyChanged(null);. Думаю для всех тоже будет работать нормально.
1
|
||
|
Модератор
|
|
| 30.01.2019, 05:05 [ТС] | |
|
kolorotur, начал дальше проверять PropertyChanged с null или Empty - не так всё просто! похоже обработка всех привязанных свойств это соглашение WPF. А само событие передаёт только параметр. Если, допустим, ловить в VM от Модели PropertyChanged, то там надо делать самому явную проверку на null или Empty и проверять все нужные свойства Модели.
Наверное WPF так и делает. Получив null или Empty проверяет весь список привязок к этому объекту.
0
|
|
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||
| 30.01.2019, 08:35 | ||||
Сообщение было отмечено Элд Хасп как решение
Решение
![]() Передача null не означает, что событие будет вызвано 100500 раз — отдельно для каждого свойства и автоматом. Оно лишь означает, что если вы получили null в обработчике, то значит объект уведомляет вас о том, что все его свойства изменились. А что делать с этой информацией — это уже ваше дело как получателя. WPF, например, обновляет все привязки этого объекта.
2
|
||||
|
|
||||||
| 25.08.2020, 16:52 | ||||||
|
Элд Хасп, в какой момень происходит инициализация PropertyChanged? У меня он почему-то всё время null.
0
|
||||||
|
|
||
| 25.08.2020, 21:28 | ||
|
0
|
||
|
Модератор
|
|||||||
| 25.08.2020, 22:31 [ТС] | |||||||
|
Если записать по старому, то код равносилен такому:
0
|
|||||||
|
Модератор
|
|||||||
| 08.10.2020, 11:35 [ТС] | |||||||
|
Это верно для WPF, но в UWP надо использовать только значение string.Empty.В связи с чем метод лучше определять так:
0
|
|||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||||
| 08.10.2020, 13:25 | |||||||
0
|
|||||||
|
Модератор
|
|||
| 08.10.2020, 13:34 [ТС] | |||
|
Но я не нашёл как именно в UWP интерпретируется null. Может игнорируется, а может тоже что-то значит... Всё что я видел:
Добавлено через 1 минуту Кстати, стало сейчас любопытно: А что будет если sender=null ? Надо проверить,... если не забуду. Добавлено через 38 секунд Или sender указывает на другой объект?
0
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||
| 08.10.2020, 13:50 | ||||
![]() Зачем?
0
|
||||
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 216
|
|
| 01.08.2023, 13:25 | |
|
Где если не здесь поспрашивать о том, а что есть Модель.
Допустим у меня есть десктопный клиент состоящий из View и класса VM, VM состоит из всякой логики обрабатывающей данные, и ссылки на класс реализующий патерн UnitOfWork(обобщенные IRepository), UnitOfWork(IRepository) взаимодействует с бекэнд сервером, где данные проверяются и отправляются в БД. То есть как-то так: View ViewModel IUnitOfWork(IRepository) BackEndServer DataBase И возникает вопрос, что в этой цепочке описывается понятием модель?
0
|
|
|
|
|||
| 01.08.2023, 13:56 | |||
|
2
|
|||
|
Модератор
|
|||
| 01.08.2023, 14:09 [ТС] | |||
|
В свою очередь он может разбиваться ещё на подслои, сервисы и т.д. Репозиторий - этот подслой Модели. BackEndServer - это часть реализации Репозитория. DataBase - по сути, некое API для работы с физ. хранилищем. Всё это входит "внутрь" Модели. Очень часто под Моделью имеют ввиду не всю Модель целиком, а только ту её публичную часть (Интерфейс) через которую взаимодействуют с ней её потребители. Особенно это актуально в рамках реализации паттернов семейства MV*. Паттерны не рассматривают вопросы внутренней реализации слоёв, а регулируют только требуемый от них функционал и правила взаимодействия друг с другом.
1
|
|||
| 01.08.2023, 14:09 | |
|
Помогаю со студенческими работами здесь
20
WPF конвертеры [Элд Хасп]
WPF vs WinForms (для начинающих) [Элд Хасп] WPF команды и MVVM. Часть 2. Всплытие команд. Реализация команды для списка элементов [WPF, Элд Хасп] Обсуждение темы "Библиотека элементов для реализации WPF MVVM Решений" [WPF, Элд Хасп] Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Новый ноутбук
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
— Расскажи мне о Мире, бродяга,
Ты же видел моря и метели.
Как сменялись короны и стяги,
Как эпохи стрелою летели.
- Этот мир — это крылья и горы,
Снег и пламя, любовь и тревоги,
И бескрайние. . .
|