Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Упражнение 2. Использование ресурсов как статических свойств и полей классов






Механизм доступа к ресурсам построен таким образом, что ресурсы можно создавать в обычном классе, а затем по мере надобности извлекать их оттуда. Это относится как к пользовательским, так и к библиотечным классам.

В WPF заготовлены 3 специальных библиотечных класса, хранящие наиболее востребованные ресурсы. Это классы SystemColors, SystemFonts и SystemParameters - все они находятся в пространстве имен System.Windows сборки PresentationFramework.dll и являются частью WPF. В пространстве имен System.Drawing тоже имеются одноименные классы SystemColors и SystemFonts, но они относятся к технологии Windows Forms и никакого отношения к рассматриваемым ресурсам не имеют.

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

Ключевым компонентом в месте извлечения статического свойства или поля является служебное слово x: Static, настраивающее синтаксический анализатор на поиск такого ресурса. В предыдущем упражнении мы уже подобным синтакисом пользовались для извлечения системного цвета при определении кисти в ресурсе файла App.xaml так

<! -- Определение ресурсов в коллекции приложения --> < Application.Resources> < SolidColorBrush x: Key=" ControlColorBrush" Color=" {x: Static SystemColors.ControlColor}" /> < /Application.Resources>

Присоединение ресурса кисти к целевому элементу в файле Window1.xaml мы задали в синтаксисе расширения разметки так

< Window x: Class=" UseResource.Window1" xmlns=" https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x=" https://schemas.microsoft.com/winfx/2006/xaml" Title=" UseResource" MinHeight=" 300" MinWidth=" 300" Height=" 300" Width=" 300" Background=" {StaticResource ControlColorBrush}" >...............................................< /Window>

Если посмотреть свойства любого из классов SystemColors, SystemFonts или SystemParameters, то они существуют парами: одно свойство представляет объект, а парное свойство представляет ключ с добавкой Key. Например, MenuBarBrush и MenuBarBrushKey. Все свойства с окончанием Key возвращают объект ключа типа ComponentResourceKey. Соответственно, существуют и два синтаксиса: извлечение самого объекта и извлечение объекта по ключу.

Извлекаемое статическое свойство или поле должны соответствовать по типу целевому элементу так, чтобы синтаксический анализатор мог легко их конвертировать. Если свойство представляет нужный тип, то его сразу можно использовать без предварительного размещения в коллекции ресурсов окна. Так например, цвет фона окна можно сразу задать одним из следующих способов (все способы эквивалентны)

< Window.................................................... Background=" {x: Static SystemColors.MenuBarBrush}" >....................................................< /Window> < Window.................................................... Background=" {DynamicResource {x: Static SystemColors.MenuBarBrushKey}}" >....................................................< /Window> < Window.................................................... > < Window.Background> < x: Static Member=" SystemColors.MenuBarBrush" /> < /Window.Background>....................................................< /Window> < Window.................................................... > < Window.Background> < DynamicResourceExtension> < DynamicResourceExtension.ResourceKey> < x: Static Member=" SystemColors.MenuBarBrushKey" /> < /DynamicResourceExtension.ResourceKey> < /DynamicResourceExtension> < /Window.Background>....................................................< /Window>

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

< Window xmlns=" https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x=" https://schemas.microsoft.com/winfx/2006/xaml" xmlns: custom1=" clr-namespace: System; assembly=mscorlib" xmlns: custom2=" clr-namespace: MyNamespace"................................................. >.................................................< /Window>

Продемонстрируем сказанное на простом приложении.

  • Добавьте к решению командой File/Add/New Project новый проект типа WPF Application с именем UseStaticMember и назначьте его стартовым
  • Заполните файл Window1.xaml следующим исходным кодом разметки
< Window x: Class=" UseStaticMember.Window1" xmlns=" https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x=" https://schemas.microsoft.com/winfx/2006/xaml" Title=" Использование статических членов классов как ресурсы" SizeToContent=" WidthAndHeight" WindowStartupLocation=" CenterScreen" ResizeMode=" CanResizeWithGrip" > < StackPanel> < /StackPanel> < /Window>
  • Добавьте в открывающий дескриптор окна библиотечный ресурс (объект) определения параметра цвета фона по синтаксису расширения разметки
< Window x: Class=" UseStaticMember.Window1" xmlns=" https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x=" https://schemas.microsoft.com/winfx/2006/xaml" Title=" Использование статических членов классов как ресурсы" SizeToContent=" WidthAndHeight" WindowStartupLocation=" CenterScreen" ResizeMode=" CanResizeWithGrip" Background=" {x: Static SystemColors.MenuBarBrush}" > < StackPanel> < /StackPanel> < /Window>
  • Добавьте в открывающий дескриптор компоновочной панели код определения префиксов пространств имен системной сборки и сборки текущего проекта (для текущего проекта сборку можно не указывать, если ее имя совпадает с пространством имен)
< StackPanel xmlns: s=" clr-namespace: System; assembly=System" xmlns: my=" clr-namespace: UseStaticMember" > < /StackPanel>
  • Поместите в компоновочную панель файла Window1.xaml следующий код разметки (файл приводится полностью)
< Window x: Class=" UseStaticMember.Window1" xmlns=" https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x=" https://schemas.microsoft.com/winfx/2006/xaml" Title=" Использование статических членов классов как ресурсы" SizeToContent=" WidthAndHeight" WindowStartupLocation=" CenterScreen" ResizeMode=" CanResizeWithGrip" Background=" {x: Static SystemColors.MenuBarBrush}" > < StackPanel xmlns: s=" clr-namespace: System; assembly=mscorlib" xmlns: my=" clr-namespace: UseStaticMember" > < TextBlock TextAlignment=" Center" FontFamily=" Arial" Foreground=" Red" FontWeight=" Bold" FontSize=" 14" > < LineBreak /> Ресурсы из статических свойств системных классов < /TextBlock> < TextBlock> < Label Content=" OSVersion: " /> < Label Content=" {x: Static my: UserClass.OSVersion}" /> < LineBreak /> < Label Content=" Version: " /> < Label Content=" {x: Static my: UserClass.Version}" /> < LineBreak /> < Label Content=" DateTime: " /> < Label Content=" {x: Static my: UserClass.DateTime}" /> < LineBreak /> < LineBreak /> < Label Content=" MachineName: " /> < Label Content=" {x: Static s: Environment.MachineName}" /> < LineBreak /> < Label Content=" UserName: " /> < Label Content=" {x: Static s: Environment.UserName}" /> < LineBreak /> < Label Content=" UserDomainName: " /> < Label Content=" {x: Static s: Environment.UserDomainName}" /> < LineBreak /> < Label Content=" SystemDirectory: " /> < Label Content=" {x: Static s: Environment.SystemDirectory}" /> < LineBreak /> < Label Content=" CurrentDirectory: " /> < Label Content=" {x: Static s: Environment.CurrentDirectory}" /> < LineBreak /> < Label Content=" CommandLine: " /> < Label Content=" {x: Static s: Environment.CommandLine}" /> < LineBreak /> < Label Content=" ExitCode: " /> < Label Content=" {x: Static s: Environment.ExitCode}" /> < LineBreak /> < Label Content=" HasShutdownStarted: " /> < Label Content=" {x: Static s: Environment.HasShutdownStarted}" /> < LineBreak /> < TextBlock Padding=" 10, 0, 10, 0" Background=" {x: Static my: UserClass.backgroundBrush}" Foreground=" {x: Static my: UserClass.foregroundBrush}" FontSize=" {x: Static my: UserClass.FontSize}" > < TextBlock.FontFamily> < x: Static Member=" my: UserClass.FontFamily" /> < /TextBlock.FontFamily> Ресурсы из статических полей нашего класса < /TextBlock> < /TextBlock> < /StackPanel> < /Window>
  • В застраничном файле процедурного кода Window1.xaml.cs создайте класс с именем UserClass и определите в нем статические члены (static members) следующим образом (файл приводится полностью)
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace UseStaticMember{ public partial class Window1: Window { public Window1() { InitializeComponent(); } } public static class UserClass { // Статические поля только для чтения public static readonly LinearGradientBrush backgroundBrush = // Имя любое new LinearGradientBrush(Colors.Blue, Colors.White, new Point(0.5, 0.5), new Point(1, 1)); public static readonly LinearGradientBrush foregroundBrush = // Имя любое new LinearGradientBrush(Colors.Red, Colors.White, new Point(1, 1), new Point(0, 0)); public static readonly Double FontSize = 24; // Имя любое public static readonly FontFamily FontFamily = // Имя любое new FontFamily(" Times New Roman Italic"); // Статические свойства доступа public static String OSVersion // Имя любое { get { return Environment.OSVersion.ToString(); } } public static String Version // Имя любое { get { return Environment.Version.ToString(); } } public static String DateTime // Имя любое { get { return System.DateTime.Now.ToString(); } } }}
  • Запустите приложение - результат будет следующим

 

К приведенному коду следует сделать несколько замечаний.

  1. Когда синтаксический анализатор компилирует разметку, то он способен автоматически приводить только простые типы, такие как string, int, bool, double. Более сложные типы он конвертировать не может и мы три типа: OSVersion, Version, DateTime.Now преобразуем в коде статических свойств класса
  2. Статические поля не обязательно объявлять только для чтения и ключевое слово readonly можно из кода убрать
  3. Ключевое слово static из объявления заголовка класса тоже можно убрать. Компилятор сам знает, что по классу со статическими членами нельзя создавать экземпляры и, в случае необходимости, присечет такие попытки программиста еще на этапе компиляции
  4. При объявлении свойств и полей можно, в том числе, применять и имена, совпадающие с системными. В разметке они будут адресоваться как принадлежащие пользовательскому классу. Но если в теле свойства, как в DateTime, применяется системное имя, то его нужно прописывать полностью с префиксом библиотечного пространства имен - System.DateTime
  • Разберитесь с кодом упражнения





© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.