Реализация логики доступности источников команд
- В соответствии с логикой работы подобных приложений заполните заготовки обработчиков события CanExecute в файле EnabledControls.cs следующим образом (комментарии в коде)
- Запустите приложение и убедитесь... - что все работает не так как надо!!!
Исправим это. Начнем с журнала откатов, встроенного в элемент TextBox. По логике, очередь изменений должна очищаться при создании нового документа или открытии существующего. А эта задача у нас выполняется в обработчиках NewOnExecute() и OpenOnExecute().
- Откройте файл File.cs и добавьте в упомянутые обработчики код очистки журнала изменений объекта txtBox1 следующим образом
- Откройте файл Edit.cs и добавьте в обработчик UndoOnExecute() следующий код
- Запустите приложение и убедитесь... - что опять все работает не так как надо!!!
Вроде бы все предусмотрели, в чем здесь дело?
- Проставьте в файле Edit.cs вдоль левого поля в теле обработчиков UndoOnExecute(), RedoOnExecute(), CutOnExecute(), CopyOnExecute(), PasteOnExecute(), DeleteOnExecute(), SelectAllOnExecute() напротив исполнимого кода точки останова (Breakpoin), как показано на снимке
увеличить изображение
>
- Запустите приложение и поэксперименируйте с источниками команд - ни один из отмеченных обработчиков (кроме DeleteOnExecute, да и тот на жест Del не реагирует) не срабатывает, хотя текстовый элемент свои функции выполняет исправно
Это происходит из-за того, что для соответствующих задач мы использовали библиотечные команды, которые напрямую работают с текстовыми элементами, имеющими фокус ввода. Ну работают и пусть себе работают, поскольку в наших обработчиках предусмотрена та же самая функциональность, кроме UndoOnExecute().
- Удалите все точки останова командой оболочки Debug/Delete All Breakpoints
- Теперь в файле EnabledControls.cs проставляйте поодиночке точки останова и каждый раз запускайте приложение для обработчиков UndoCanExecute(), RedoCanExecute(), CutCanExecute(), CopyCanExecute(), PasteCanExecute(), DeleteCanExecute(), SelectAllCanExecute(). Для остановки процесса пользуйтесь командой Stop Debugging меню Debug оболочки или одноименной кнопкой панели инструментов!!!
Мы видим, что все эти обработчики события CanExecute срабатывают исправно для всех команд: и библиотечных, и пользовательских. Причем срабатывают перед тем, как элемент показывается при раскрытии меню, начальной отрисовке или наведении курсора. То есть срабатывает именно тогда, когда нужно принять решение, с какой доступностью этот элемент отобразить.
Итак, для правильной работы логики доступности источников команд нам нужно заставить выполняться именно наши обработчики для команд Undo, Redo и SelectAll.
- Добавьте в статический конструктор файла EnabledControls.cs следующий код переопределения библиотечных команд на пользовательские
Обратите внимание на то, что мы не удалили в полях инициализацию переопределенных ссылок библиотечными командами. Мы понадеялись на порядок инициализации полей и срабатывания статического конструктора. Вначале вынесенные в поля класса ссылки на команды объявляются и инициализируются, а затем в статическом конструкторе эти же ссылки получают адреса новых команд. Это малоприметный, но очень важный нюанс, проигнорировав который можно получить неуловимую ошибку выполнения.
Это плохая практика программирования, поскольку завтра могут выпустить другой транслятор или среду исполнения CLR, где этот порядок будет изменен, и наша программа станет работать неверно. Microsoft не дремлет (!!!) и регулярно посылает по сети обновления и исправления. А что они завтра пришлют, кто его знает. Поэтому лучше было бы в полях ссылки только объявить, а уже в конструкторе они бы наверняка получили адреса наших (пользовательских) команд. Можете так и сделать, но я у себя оставляю как есть.
- Запустите приложение - теперь все работает как надо!!!
Мы спроектировали более-менее сносный текстовый редактор, для этого спукались на относительно низкий (подробный) уровень программирования. Конечно, в получившемся продукте еще много недоработок, да и такую задачу можно было бы решить в два счета на C++Builder. Но мы-то не блокнот проектировали, а знакомились с новым механизмом команд WPF на примере блокнота.
Вначале мы попытались проектировать без привлечения команд. Создали основу блокнота, но управление доступностью источников реализовали только для одной задачи Save, и то с большим трудом. Приходилось пускаться на всякие ухищрения. Затем часть задач переключили на команды. И сразу удалось гораздо легче и понятнее реализовать доступность всех источников пользовательского интерфейса. Выгода от применения механизма команд очевидна.
Дата добавления: 2015-04-15; просмотров: 773;