Ресурсы и код

В этом обзоре основное внимание уделяется доступу к ресурсам Windows Presentation Foundation (WPF) или созданию с помощью кода, а не синтаксиса языка разметки XAML. Дополнительные сведения об общем использовании ресурсов и ресурсах с точки зрения синтаксиса XAML см. в статье "Ресурсы XAML".

Доступ к ресурсам из кода

Ключи, идентифицирующие ресурсы, если они определены через XAML, также используются для извлечения определенных ресурсов при запросе ресурса из кода. Самым простым способом извлечения ресурса из кода является вызов метода FindResource или TryFindResource из объектов уровня платформы в приложении. Различие между этими методами проявляется, если запрошенный ключ не найден. FindResource создает исключение, а TryFindResource не создает исключение, а возвращает null. Каждый из этих методов принимает ключ ресурса в качестве входного параметра и возвращает объект со слабой типизацией. Как правило, ключ ресурса является строкой, но иногда используются и нестроковые ключи. Подробнее см. в разделе Использование объектов в качестве ключей. Как правило, возвращаемый объект приводится к типу, необходимому для свойства, которое устанавливается при запросе ресурса. Логика поиска разрешения ресурса кода такая же, как и в случае динамической ссылки на ресурс XAML. Поиск ресурсов начинается с вызывающего элемента, затем продолжается в последовательных родительских элементах в логическом дереве. При необходимости поиск продолжается в ресурсах приложений, темах и системных ресурсах. Запрос кода для ресурса будет правильно учитывать изменения во время выполнения в словарях ресурсов, которые могли быть сделаны после загрузки данного словаря из XAML, а также изменения системных ресурсов в реальном времени.

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

void SetBGByResource(object sender, RoutedEventArgs e)
{
  Button b = sender as Button;
  b.Background = (Brush)this.FindResource("RainbowBrush");
}
Private Sub SetBGByResource(ByVal sender As Object, ByVal e As RoutedEventArgs)
  Dim b As Button = TryCast(sender, Button)
  b.Background = CType(Me.FindResource("RainbowBrush"), Brush)
End Sub

Альтернативным методом назначения ссылки на ресурс является SetResourceReference. Этот метод принимает два параметра — ключ ресурса и идентификатор конкретного свойства зависимостей из экземпляра элемента, которому должно быть присвоено значение ресурса. Функционально этот метод аналогичен, но имеет преимущество в том плане, что не требует приведения возвращаемых значений.

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

Можно индексировать любую заданную коллекцию Resources, используя в качестве индекса определенный ключ, но необходимо учитывать, что доступ к ресурсу таким образом не соответствует обычным правилам среды выполнения для разрешения ресурса. У вас будет только доступ к этой конкретной коллекции. Поиск ресурсов не будет пересекать область действия корня или приложения, если в запрашиваемом ключе не найден действительный объект. Тем не менее в некоторых случаях этот подход может иметь преимущество в производительности, поскольку область поиска ключа более ограничена. Дополнительные сведения о работе со словарями ресурсов напрямую см. в классе ResourceDictionary.

Создание ресурсов с помощью кода

Пи создании приложения WPF полностью в коде может также понадобиться создать в коде все ресурсы в этом приложении. Для этого создайте новый экземпляр ResourceDictionary, а затем добавьте все ресурсы в словарь с помощью последовательных вызовов в ResourceDictionary.Add. Затем используйте созданный ResourceDictionary, чтобы задать свойство Resources в элементе, который присутствует в области страницы, или Application.Resources. Можно также работать с ResourceDictionary как с автономным объектом, не добавляя его в элемент. Однако в этом случае для доступа к ресурсам внутри него потребуется ключ элемента, как для общего словаря. ResourceDictionary, который не привязан к свойству Resources элемента, не будет существовать в качестве части дерева элементов и не будет иметь область в последовательности поиска, которая может быть использована FindResource и связанными методами.

Использование объектов в качестве ключей

В большинстве случаев использования ресурса ключ ресурса устанавливается в виде строки. Однако различные функции WPF намеренно не используют строковый тип для указания ключей. Вместо этого параметр является объектом. Возможность доступа объекта к ресурсу по ключу используется в поддержке стилей и тем WPF. Стили в темах, которые становятся стилем по умолчанию для элемента управления без стиля, вводятся с помощью ключа типом Type элемента управления, к которому они должны применяться. Ввод с помощью ключа по типу обеспечивает надежный механизм поиска, который работает со стандартными экземплярами каждого типа элемента управления, а тип может быть обнаружен отражением и использоваться для создания стилей производных классов, даже если у производного типа нет стиля по умолчанию. Ключ для ресурса, определенного в XAML, можно указать Type с помощью расширения разметки x:Type. Аналогичные расширения существуют для других нестроковых ключевых использования, поддерживающих функции WPF, такие как расширение разметки ComponentResourceKey.

См. также