Ресурсы и код
Обновлен: Ноябрь 2007
Этот обзор сосредоточен на том, как Windows Presentation Foundation (WPF) ресурсы могут быть доступны или созданы с помощью кода, а не синтаксиса Язык XAML (Extensible Application Markup Language). Дополнительные сведения об общем использовании ресурсов и ресурсов с точки зрения синтаксиса 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");
}
Альтернативным способом назначения ссылки ресурса является SetResourceReference. Этот метод принимает два параметра: ключ ресурса и идентификатор для конкретного свойства зависимостей, которое присутствует в экземпляре элемента, которому должно быть назначено значение ресурса. Функционально, этот метод аналогичен и имеет преимущество в том, что не требует приведения возвращаемых значений.
Другим способом для получения программного доступа к ресурсам по-прежнему является доступ к содержимому свойства Resources в качестве словаря. Доступ к словарю, содержащегося в этом свойстве, также является способом, с помощью которого можно добавить новые ресурсы в существующие коллекции, проверить, существует ли в коллекции данное имя ключа, и выполнить другие операции с коллекциями/словарями. При написании приложения WPF целиком в коде можно также создать всю коллекцию в коде, назначить для нее клавиши и затем присвоить завершенную коллекцию свойству Resources установленного элемента. Это будет описано в следующем разделе.
Можно индексировать любую заданную коллекцию Resources, используя определенный ключ в качестве индекса, но нужно знать, что доступ к ресурсу таким образом не соответствует обычным правилам времени выполнения разрешения ресурсов. Осуществляется доступ только к этой конкретной коллекции. Если не был найден допустимый объект по запрашиваемому ключу, то поиск ресурса не будет проходить область или приложение до корневого элемента. Однако этот подход может иметь преимущество в производительности в некоторых случаях, поскольку область поиска ключа более ограничена. Дополнительные сведения о работе со словарями ресурсов напрямую см. в описании класса ResourceDictionary.
Создание ресурсов с помощью кода
Если создается WPF приложение целиком в коде, может потребоваться создавать ресурсы в этом приложении также в коде. Для этого создайте новый экземпляр ResourceDictionary, а затем добавьте все ресурсы в словарь, последовательно вызывая ResourceDictionary.Add. Затем используйте созданный таким образом словарь ResourceDictionary, чтобы установить свойство Resources элемента, который присутствует в области страницы, или Application.Resources. Можно также хранить ResourceDictionary в качестве автономного объекта, без добавления его в элемент. Тем не менее, если это выполняется, необходимо получить доступ к его внутренним ресурсам по ключу элемента, как если бы это был универсальный словарь. Словарь ResourceDictionary, который не присоединен к свойству Resources элемента, не будет существовать как часть дерева элементов и не будет иметь область в последовательности поиска, которая может использоваться объектом FindResource и соответствующими методами.
Использование объектов в качестве ключей
В большинстве случаев использования ресурсов задается ключ ресурса в виде строки. Однако различные функции WPF намеренно не используют строковый тип для указания ключей, вместо этого параметр является объектом. Возможность определения ресурса по ключу с помощью объекта используется поддержкой стиля WPF и тем. Стили в темах, которые становятся стилем по умолчанию для элемента управления без стиля, определяются по ключу с помощью Type элемента управления, к которому они применяются. Поиск по ключу с помощью типа предоставляет надежный механизм поиска, который работает с экземплярами по умолчанию каждого типа элемента управления, а тип может быть определен с помощью отражения и использован для стилизации производных классов, даже через производный тип, который не имеет стиля по умолчанию. Можно указать ключ Type для ресурса, определенного в XAML с помощью Расширение разметки x:Type. Аналогичные расширения существуют для других случаев использований нестрокового ключа, который поддерживает функции WPF, такие как Расширение разметки ComponentResourceKey.