пятница, 1 августа 2008 г.

Kodama - a spirit of tree.

Те из вас, кто читает мою англоязычную версию блога, возможно, читали мою заметку про то как ViewModel спасает людей (вообще говоря ViewModel капризничает и спасает только WPF developer'ов ). Мне было недосуг переводить ее, но вот вкратце ее содержание: хотите облегчить себе жизнь - используйте ViewModel где только возможно. В данном случае я использовал ViewModel при работе с ComboBox. Что из этого вышло? Вышел замечательный и удобный класс SelectorCollectionPresenter, жить с которым намного легче. =) В конце я в качестве бонуса опубликую его код. А сейчас я хочу написать не об этом.

Хочу написать я о ViewModel, взаимодействующем с TreeView. Вдохновение меня посетило когда я прочитал вот эту статью Josh'а Smith'а. C тех пор прошло уже много времени и я почти не работал с WPF непосредственно, а больше решал инфраструктурные проблемы (я начал серию заметок про масло масляное), но идея мне понравилась и засела в голове.

И вот, наконец, я обобщил и собрал воедино свое видение этой проблемы. В результате был написан контрол имитирующий TreeView "с душой". Назвал я его KodamaView. Kodama в японской мифологии - это дух живущий в дереве. А Kodama моего дерева, как вы наверное уже догадались это ViewModel.

- он сказал ViewModel?

Хочу сразу предупредить, что я просто собрал воедино в повторно используемый компонент свои наработки и идеи Josh'а.

KodamaView

KodamaView - это UserControl, который хостит внутри себя TreeView. Дабы сымитировать поведение TreeView он реализует интерфейс ITreeView, унаследованный от моего
базового интерфейса IWPFView путем делегирования всех вызовов внутреннему TreeView.


интерфейс для имитации TreeView.


Собственно сам контрол.


Стили и темплейты.

Kodama.

И теперь о самом главном - о душе.


Вот она душа дерева на картине
Toriyama Sekien

Моя кодама (если можно так выразиться) - это наследник класса ViewModel, параметризованного интерфейсами ITreeView и IDataModelBase. Последний объявлен базовым для того, чтобы ему подсунуть любую DataModel. Обновив ее, наследник Kodama получит список или иерархию объектов, которые отрендерит TreeView.

Для каждого TreeViewItem'а создается своя Kodama - TreeViewItemViewModel.



В данном классе предусмотрена возможность "ленивой" загрузки дочерних элементов при раскрытии узла (метод LoadChildren должен быть переопределен в наследниках) (честно сперто у Josh'а).



И наконец, я написал generic-класс TreeViewItemViewModel`1, единственное назначение которого - публиковать сущность для привязки в шаблоне.



В качестве примера - Kodama дерева департаментов.




А вот и бонус - SelectorCollectionPresenter. За всеми подробностями сюда.



Удачи!

Комментариев нет: