Главная » Silverlight » Иерархия ресурсов

0

Каждый элемент обладает собственной коллекцией ресурсов, и Silverlight выполняет рекурсивный поиск нужного ресурса вверх по дереву элементов. Рассмотрим следую­щую разметку.

<UserControl x:Class="Resources.ResourceHierarchy" xmlns="http://schemas.microsoft .com/winfx/2 00 б/1^

xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White">

<StackPanel>

<StackPanel.Resources> <LinearGradientBrush x:Key="ButtonFace"> <GradientStop Offset="0.00" Color="Yellow" /> <GradientStop Offset="0.50" Color="White" /> <GradientStop Offset="l.00" Color="Purple" /> </LinearGradientBrush> </StackPanel.Resources>

<Button Content="Первая кнопка" Margin="5" Background="{StaticResource ButtonFace}"></Button> <Button Content="BTopaH кнопка" Margin="5" Background="{StaticResource ButtonFace}"></Button> </StackPanel>

</Grid> </UserControl>

На рис. 2.2 показана страница, созданная этой разметкой1.

Рис. 2.2. Использование одной кисти для заливки двух кнопок

Фон обеих кнопок устанавливается на основе одного и того же ресурса. Проходя по приведенной выше разметке, Silverlight сначала проверяет коллекцию ресурсов самой кнопки, а затем — ее родительского элемента StackPanel (если он существует). Если же и в StackPanel нет нужного ресурса, Silverlight продолжает его поиск, перейдя сначала к коллекции ресурсов элемента Grid, а затем — элемента UserControl. Если и после этого ресурс с заданным именем не будет найден, Silverlight проверяет ресурсы прило­жения, определенные в разделе <Application.Resources> файла App.xaml.

<Application xmlns=

"http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2 00 6/xaml" x:Class="SilverlightApplicationl.App"> <Application.Resources> CLinearGradientBrush x:Key="ButtonFace"> <LinearGradientBrush.GradientStops> <GradientStop 0ffset="0.00" Color="Yellow" /> <GradientStop Offset="0.50" Color="White" /> <GradientStop Offset="l.00" Color="Purple" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Application.Resources>

</Application>

Піавное преимущество размещения ресурсов в коллекции приложения состоит в том, что при этом они полностью удаляются из разметки страницы. Кроме того, их можно повторно использовать во всем приложении. В рассмотренном примере в ресурсах приложения можно хранить кисть, используемую на разных страницах.

Примечание. Перед созданием ресурсов приложения оцените баланс между сложностью и возможностью повторного использования. Ресурсы приложения можно многократно использовать во многих местах, однако их применение усложняет код, поэтому их целесообразность не очевидна. Рекомендуется использовать ресурсы приложения, если они применяются на многих страницах. Если же они нужны не более чем на двух или трех страницах, лучше определить ресурсы на уровне каждой страницы.

При определении ресурса в разметке важна последовательность элементов. Необходимо размещать определение ресурса перед его использованием в разметке. Например, если разместить раздел <StackPanel .Resources> после разметки, в которой объявляются кнопки, документ XAML будет валидным, однако приложение не будет ра­ботать. Встретив во время выполнения ссылку на незнакомый ресурс, синтаксический анализатор XAML сгенерирует исключение.

Обратите внимание на то, что имена ресурсов могут повторяться. Важно лишь, чтобы одноименные, но разные ресурсы находились в разных коллекциях. Если в одной кол­лекции два разных ресурса имеют одно имя, Silverlight применит ресурс, встретившийся первым. Это позволяет определить ресурс в коллекции ресурсов приложения, а затем при необходимости переопределить его на некоторых страницах, заменив другим ресурсом.

Обращение к ресурсам в коде

Обычно ресурсы определяются и используются в разметке. Однако при необходимо­сти коллекции ресурсов можно обрабатывать в коде. Наиболее простой способ состоит в обращении к ресурсу, размещенному в соответствующей коллекции, по имени. На­пример, если кисть LinearGradientBrush хранится в разделе <UserControl .Resources> под именем ButtonFace, ею можно манипулировать в коде следующим образом.

LinearGradientBrush brush =

(LinearGradientBrush)this.Resources["ButtonFace"];

// Поменять цвета местами

Color color = brush.GradientStops [0] .Color;

brush.GradientStops[0].Color = brush.GradientStops[2].Color;

brush.GradientStops[2].Color = color;

Существует одно важное ограничение. Платформа Silverlight не поддерживает дина­мические ресурсы, поэтому изменить ссылку на ресурс невозможно. Это означает, что

При изменении ресурса в коде автоматически обновляется каждый элемент, в кото­ром он используется. Например, при щелчке на верхней кнопке изменяется цвет обеих кнопок (рис. 2.3).

Рис. 2.3. Изменение ресурса

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

SolidColorBrush brush = new SolidColorBrush(Colors-Yellow); this.Resources["ButtonFace"] = brush;

Чтобы не просматривать коллекцию ресурсов в поиске нужного объекта, присвойте ресурсу имя с помощью атрибута Name. Затем к ресурсу можно обратиться в коде непо­средственно по имени. Однако присвоить одному и тому же объекту одновременно имя и ключ невозможно. Расширение разметки StaticResource распознает только ключи. Следовательно, если создан именованный ресурс, его нельзя будет использовать в разметке с помощью ссылки StaticResource. По этой причине ключи используются чаще, чем имена.

Словари ресурсов

Чтобы совместно применять одни и те же ресурсы в нескольких проектах и лучше организовать сложные, насыщенные ресурсами, проекты, создайте словарь ресурсов — документ XAML, который не делает ничего, кроме того, что хранит набор ресурсов. Для создания словаря ресурсов в Visual Studio щелкните правой кнопкой мыши на про­екте в окне Solution Explorer (Проводник решений) и выберите команду Add?New Item (Добавить?Новый элемент). Выберите шаблон Silverlight Resource Dictionary (Словарь ре­сурсов Silverlight), введите желаемое имя и щелкните на кнопке Add (Добавить).

Ниже приведен пример словаря ресурсов ElementBrushes.xaml, в котором определен один ресурс.

<ResourceDictionary

xmlns="http://schemas.microsoft.com/winfx/2006/

xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

CLinearGradientBrush x:Key="ButtonFace"> CLinearGradientBrush.GradientStops> <GradientStop 0ffset="0.00" Color="Yellow" /> <GradientStop 0ffset="0.50" Color="White" /> <GradientStop Offset="l.00" Color="Purple" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </ResourceDictionary>

Чтобы применить словарь ресурсов, нужно включить его в коллекцию ресурсов где- либо в приложении. Это можно сделать на отдельной странице, однако чаще словари включаются в коллекцию ресурсов приложения, как показано ниже.

<Application xmlns="http://schemas.microsoft.com/

client/2007"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplicationl.App"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="ElementBrushes.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>

Коллекция MergedDictionaries содержит объекты ResourceDictionary, кото­рые можно использовать как дополнение коллекции ресурсов. В данном примере применяется только один словарь, однако в коллекции можно объединить произвольное количество словарей. Чтобы добавить собственные ресурсы и включить их в словари ре­сурсов, разместите ресурсы до или после раздела MergedProperties, как показано ниже.

<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="BasicBrushes.xaml" /> <ResourceDictionary Source="ButtonBrushes.xaml" /> </ResourceDictionary.MergedDictionaries> <LinearGradientBrush x:Key="GraphicalBrushl" … >

</LinearGradientBrush> CLinearGradientBrush x:Key="GraphicalBrush" … > </LinearGradientBrush> </ResourceDictionary> </Application.Resources>

Примечание. Как вы уже знаете, зачастую имеет смысл хранить ресурсы с одним и тем же именем в разных, но перекрывающихся коллекциях ресурсов. Однако объединять словари ресурсов с одними и теми же именами ресурсов нельзя. Если во время компиляции приложения будет обнаружен дубликат, программа сгенерирует исключение.

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

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии