Свойства в шаблоне команд

Как мы обрабатываем простые установщики общедоступных свойств в шаблоне команд, чтобы сделать их отключаемыми? Нужно ли мне создавать отдельную команду для каждого свойства?

Подробности

Мое приложение (WPF / MVVM / C #) в настоящее время реализует функцию отмены / повтора, поддерживая стек «снимков состояния». Эти снимки создаются после каждого действия, которое невозможно отменить, и помещаются в стек. Хотя этот подход до сих пор работал правильно, размер стека отмены продолжает увеличиваться, что делает приложение менее отзывчивым.

Сейчас я рассматриваю перспективы перехода на стандартный Command Pattern. Поскольку я уже использую MVVM Light, я бы просто расширил RelayCommand, чтобы создать UndoableRelayCommand, а затем поместить их в свой стек отмены вместо снимков. Все идет нормально.

Однако проблема заключается в том, что многие объекты уровня виртуальной машины привязаны непосредственно к элементам управления пользовательского интерфейса (через стандартный WPF Binding) и поэтому устанавливаются напрямую, без участия какого-либо RelayCommand. Установка этих свойств должна быть отменяемым действием. Как мне вписать это требование в стандартный шаблон команд, сохранив при этом мои привязки нетронутыми?


person dotNET    schedule 27.02.2018    source источник
comment
Почему размер стека делает приложение менее отзывчивым? И как это исправить с помощью команд, которые добавляют в стек? Разве вы не можете просто добавить в стек свои установщики свойств с привязкой к данным?   -  person mm8    schedule 27.02.2018
comment
@ mm8: Как я уже сказал, я сериализую всю виртуальную машину после каждого действия. Память приложения начинает снимать сотни мегабайт за длительный сеанс. Используя команды, каждая команда просто сохранит достаточно информации, чтобы отменить себя, что резко уменьшит размер стека отмены (размер в МБ, а не количество записей отмены). Единственная проблема заключается в том, что простые свойства привязаны непосредственно к элементам пользовательского интерфейса.   -  person dotNET    schedule 27.02.2018
comment
Не можете ли вы вызвать соответствующую команду из установщика свойства с привязкой к данным?   -  person mm8    schedule 28.02.2018
comment
@ мм8. В этих свойствах нет никакой команды. Они напрямую привязаны к элементам пользовательского интерфейса и поэтому автоматически обновляются через Binding. Стандартный командный шаблон не включает никаких условий для таких свойств (IIRC).   -  person dotNET    schedule 28.02.2018
comment
Так в чем твой вопрос? Если команда не задействована, очевидно, что нет шаблона команды, который можно было бы применить к этим свойствам.   -  person mm8    schedule 28.02.2018


Ответы (1)


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

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

Я не понимаю, что означает, что приложение перестает отвечать. Все операции со стеком отмены / повтора должны быть O(1). Если ваша реализация более сложна, чем O(1), возможно, вам следует изучить это направление, прежде чем переделывать механизм.

В любом случае, со стеком отмены / повтора есть одна практическая уловка, обычно применяемая в более крупных приложениях. Связанный размер стопки. При добавлении большего количества элементов позвольте ему «забыть» самые старые. Еще один практический трюк, который также используется, - очищать стек каждый раз, когда состояние сохраняется, и оставлять только последнюю команду для повтора. Это те настройки производительности, которые я видел до сих пор.

person Zoran Horvat    schedule 27.02.2018
comment
Спасибо, что поделились своим мнением. создание снимка затронутого значения не вариант, потому что многие действия в моем приложении влияют на несколько свойств нескольких объектов (например, закрепить все выбранные объекты наверх). Поскольку в настоящее время я не использую Command Pattern, невозможно отслеживать только затронутое значение. Так что единственный способ, который у меня остался, - это делать снимок всей виртуальной машины при каждом отменяемом действии (то, что вы называете промахом, смеется). Именно поэтому я хочу перейти на Command Pattern. - person dotNET; 27.02.2018