Инжекторы контекста xaml

Автор: admin от 30-03-2015, 12:24, посмотрело: 356

В предыдущей части мы познакомились с расширениями привязки и разобрались, как их применять на практике, например, для локализации. Сегодня же продолжим изучать особенности библиотеки Aero Framework и рассмотрим довольно интересную тему об инжекции контекста данных в xaml-разметку представлений, а заодно применим познания из прошлой статьи.

На практике часто встречается следующая задача: связать вью-модель, которая хранится в unity-контейнере, с одним или несколькими её представлениями (экранами). Обычно такое связывание происходит в бехаинд-коде, в результате чего у представления устанавливается нужное значение в свойство DataContext.

Во многих случаях это работает хорошо, но с таким подходом сопряжены определённые нюансы и трудности. Например, они касаются контекстных меню и другой всплывающей анимации, поскольку она не входит в визуальное дерево, а следовательно, для неё становится недоступным основной контекст данных. Другой случай связан с работой списковых элементов, когда контекстом уже является элемент списка, но есть необходимость в использовании другого источника привязки. Третий вариант возникает, когда одно представление работает сразу с несколькими вью-моделями.

Все эти трудности так или иначе решаемы, но существует универсальный и очень простой способ их красиво разрешить. О нём и пойдет речь.
Инжекторы контекста xaml

Для начала определимся с терминологией. Каждый элементарный визуальный контрол — это маленькое атомарное представление. Сложные комплексные представления строятся на основе простых, образуя древовидную структуру (визуальное дерево), где каждый узел также является представлением вплоть до корня. Будем различать особый род представлений — экраны, которые в том или ином виде поддерживают навигацию и зачастую являются корневыми.

Пускай имеется единое хранилище Store, из которого по ключу извлекается нужный экземпляр объекта. Идея состоит в том, чтобы с помощью расширения xaml-разметки обеспечить возможность извлечения произвольного экземпляра объекта и дальнейшее его инжектирование в качестве контекста данных в любой узел визуального дерева.

Выглядит всё очень просто:

<Control DataContext="{Store Key=viewModels:AppViewModel}"/>

<Control>
	<Control.DataContext>
		<Store Key=viewModels:AppViewModel>
	</Control.DataContext>
</Control>

Получить доступ к вью-моделям из C#-кода также крайне легко:

var appViewModel = Store.Get[leech=http://makeloft.by/ru/tools]исходным кодам библиотеки [i]Aero Framework[/i][/leech], там всё очень прозрачно и понятно. [i]Ключом[/i] же обычно является тип вью-модели или тип интерфейса, который она реализует, но ничто не запрещает использовать любые другие.<br/>
<br/>
То есть, чтобы связать экран приложения (страницу или окно) достаточно лишь нескольких строк:<br/>
<br/>
[code]<!--WP7, WP8, WPF-->
<Page
	xmlns:viewModels="clr-namespace:AeroPlayer.ViewModels"
	DataContext="{m:Store Key=viewModels:SongViewModel}">
	...
</Page>

<!--WPF-->
<Window
	xmlns:viewModels="clr-namespace:AeroPlayer.ViewModels"
	DataContext="{Store viewModels:SongViewModel}">
	...
</Window>

<!--Windows Store, WP8.1-->
<Page xmlns:viewModels="using:AeroPlayer.ViewModels">  
    <Page.DataContext>
		<Store Key=viewModels:AppViewModel>
	</Page.DataContext>
	...
</Page>

И никакого бехаинд-кода! С контекстными меню теперь всё очень изящно:

<ContextMenu DataContext="{Store viewModels:AppViewModel}">
	...
</ContextMenu>

Но как красиво решаются подобные ситуации:

<ListBox DataContext={Store viewModels:AppViewModel} ItemsSource={Binding Persons}>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding FirstName}"/>
                <TextBlock Text="{Binding LastName}"/>
                <TextBlock 
                	Text="{Binding Age}"
                	Visibility="{StoreBinding Path=ShowDetails, StoreKey=viewModels:SettingsViewModel, Converter={StaticResource TrueToVisibleConverter}}"/>
            </StackPanel>
        </DataTemplate>
    <ListBox.ItemTemplate>
</ListBox>

Надеюсь, что вам уже захотелось применить на деле рассмотренный поход. Это и есть реализация принципа прямых инжекций (Direct Injections Principle), который предложен в статье. Отметим, у одной вью-модели может быть несколько представлений, однако обратная ситуация, когда представлене работает сразу с несколькими вью-моделями, на пракике редкость из-за описаных выше технических сложностей. Но с помощью прямых инжекций отношение вью-модель-представление запросто расширяется с однин ко многим до многие ко многим.

Спасибо за интерес!

Источник: Хабрахабр

Категория: Программирование

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *