Является ли этот подход правильным или есть ли лучший способ сделать это в шаблоне MVVM WPF?
Это, к сожалению, распространенный и принятый шаблон MVVM во всем C #.Я говорю «к сожалению», потому что этот шаблон действительно сталкивается с проблемами.Он основан на событиях - которые сами по себе проблематичны - и он также вызывает немедленное обновление , что во многих случаях нежелательно.
Для одного примера иногда желательноимеют два свойства, которые взаимозависимы - когда пользователь меняет одно, другое изменяется по отношению к нему - и это может вызвать проблемы, поскольку нет никакого способа отличить «пользовательские изменения» от «изменений кода».
В другом примере иногда вы можете получить целое дерево зависимых свойств, и может потребоваться некоторое время, чтобы все изменения распространились и перестали мешать друг другу.
Более современные подходы MVVM, такие как атомно-обновленный единый источник истины с однонаправленным потоком данных (популяризированный Redux) позволяет избежать вышеуказанных проблем.Существует реализация C # Redux;Я не знаю, как легко это использовать.В моей собственной библиотеке CalculatedProperties я построил свою собственную "очередь недействительности", чтобы обойти это, что откладывает все PropertyChanged
обновления до тех пор, пока не будет рассчитано новое устойчивое состояние всей системы.
Я пытался сделать приложение асинхронным, используя async и await, но приведенные выше сценарии вызывают проблемы, поскольку async и await не имеют концепции асинхронных свойств.
True.В частности, вы не можете «асинхронно получить» свойство.И это имеет смысл в мире MVVM;когда WPF обновляет экран и запрашивает у вашей виртуальной машины значение данных, тогда ваша виртуальная машина не может сказать «подождите, я получу это через минуту».WPF должен знать это значение сейчас , чтобы он мог обновлять экран сейчас .
Подключение обработчика асинхронных событий - это один из способов запустить асинхронную работу, когда значениеизменения;такой подход в порядке.Обычно наличие SomeIntegerChanged
подразумевает, что есть «измененное» событие специально для этого свойства , поэтому, вероятно, труднее сделать это, подключившись к PropertyChanged
с помощью сравнения строк.
Подробнее об асинхронных свойствах с MVVM см. Мою статью на тему .