четверг, августа 13, 2009

Реализация закладки для элемента управления PropertyGrid

Одной из важных фич Syringe является возможность перехватывать события, порождаемые тестируемым элементом управления.

Я решил реализовать настройку перехватчиков средствами того же PropertyGrid’а, что и используется для редактирования свойств. Тогда интерфейс оказывается максимально похож на VisualStudio и, следовательно, не вызывает удивления.

Логично было вынести список событий на отдельную закладку.

Я попробовал использовать стандартную закладку EventsTab, но не осилил. Для своей инициализации она требует слишком много зависимостей, запрашиваемых неявно через родительский контейнер. Даже если бы я уже приделал DI-контейнер (зря я это откладываю, ох, зря) и отследил все обращения, все равно я оказался бы перед необходимостью реализовывать целую кучу интерфейсов типа IDesignerHost, IEventsBindingService и пр., функциональность которых мне не очень-то нужна.

Поэтому я решил реализовать свою закладку с нуля. Ну, не совсем =) На самом деле, у родительского класса абстрактными являются только свойство TabName и метод GetProperties.

Я реализовал GetProperties так, чтобы он возвращал по PropertyDescriptor’у для каждого события в тестируемом объекте (а список событий получил через TypeDescriptor), причем для этих дескрипторов указал в качестве редактора использовать список доступных логгеров (я их реализовал два – пишущий в лог и показывающий MessageBox). Адаптацию логгеров к разным типам событий была сделана еще раньше.

Я добавил свою закладку в PropertyGrid, и, о чудо… она не появилась. Выяснилось (при просмотре в Reflector’е), что, кроме реализации абстрактных методов, есть еще одно неочевидное условие: закладка должна что-то возвращать по запросу свойства Bitmap, которое используется для выбора иконки закладки! OMFG! Перекрыв это свойство я таки достиг успеха.

Так что теперь Syringe может перехватывать события (правда, пока не умеет нормально форматировать их аргументы), а пользователь может удобно выбрать тип перехватчика. Это первая (и очень полезная, ИМХО) фича, которой принципиально нет в UserControlTestContainer.

Моя доволен =)

blog comments powered by Disqus