Главная » WPF » Ресурсы и конфигурирование

0

Есть много способов классифицировать состояние  приложения, но я предпо# читаю рассматривать только  три основных  категории:  конфигурация,  содержи# мое и документ. В .NET поддерживаются все три модели.

Конфигурация

Состояние, сводящееся к конфигурации, – это набор параметров, ассоциирован# ный с конкретным пользователем или компьютером.  Обычно  его может изменять пользователь или администратор во время  выполнения или на этапе развертыва# ния.  Средства  конфигурирования в  .NET  эволюционировали со времен  версии

.NET 1.0, и сейчас мы познакомимся с тем, как включить их в WPF#приложение.

Для  управления сохраняемыми параметрами приложения прекрасно  подой# дет API,  находящийся в пространстве  имен  System.Configuration. Углубленное изучение  системы  конфигурирования не входит  в задачу  этой книги,  но пони# мать, как эта система интегрируется с объектом Application,  необходимо.

Прежде  всего,  необходимо  определить   объектную  модель  параметров.  Это можно сделать  либо с помощью  конструктора параметров  в Visual Studio  2005, либо написав  соответствующий класс  на любом .NET#совместимом  языке.  Мы определим объектную модель на C#, поставив себе целью запомнить, сколько раз запускалась программа:

public class AppSettings {

int _runCount;

public int RunCount {

get { return _runCount; }

set { _runCount = value; }

}

}

Здесь  создано  свойство  для хранения  информации о состоянии.  Чтобы  сде# лать  его частью  системы  конфигурирования, нужно  произвести  наш  класс  от класса SettingsBase (или  ApplicationSettingsBase) и предоставить  некоторые  ме# таданные, описывающие свойство. Вместо того чтобы хранить значение в локаль# ном поле, необходимо воспользоваться хранилищем, встроенным в тип SettingsBase, чтобы система могла отслеживать изменения значения:

public class AppSettings : ApplicationSettingsBase {

public AppSettings() : base() {

}

[UserScopedSetting] [DefaultSettingValue(«0»)] public int RunCount {

get { return (int)this[«RunCount»]; }

set { this[«RunCount»] = value; }

}

}

Параметры  могут относиться  к одному пользователю или ко всем пользовате# лям (параметры уровня приложения). В данном случае мы решили, что у каждо# го пользователя будет свое значение  параметра,  поэтому применили к свойству атрибут UserScopedSetting.

После определения объектной  модели осталось сделать еще две вещи: настро# ить привязки к конфигурационному файлу  и дать к ним доступ через объект Application.  Привязки сообщают системе конфигурирования о том, как отобра# зить конфигурационный файл на только что определенную объектную модель.

Чтобы задать привязки, нужно зарегистрировать класс AppSettings в системе конфигурирования, добавив секцию в файл app.config. Этот файл в .NET являет# ся стандартным  местом для хранения  всей конфигурационной информации при# ложения. Чтобы включить файл app.config в наш проект, мы должны добавить его как элемент None (согласен, это не очень логично):

<ItemGroup>

<None Include=’app.config’ />

</ItemGroup>

На этапе компиляции система  построения  автоматически преобразует  файл app.config в файл <OurProgramName>.exe.config. После компиляции конфигура# ционный  файл будет выглядеть  примерно  так:

<?xml version=’1.0’ encoding=’utf 8’ ?>

<configuration>

<configSections>

<sectionGroup name=’userSettings’ type=’System.Configuration.UserSettingsGroup, System,

Version=2.0.0.0,

Culture=neutral, PublicKeyToken=b77a5c561934e089’>

<section name=’EssentialWPF.AppSettings’ type=’System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral,

PublicKeyToken=b77a5c561934e089’

allowExeDefinition=’MachineToLocalUser’

requirePermission=’false’

/>

</sectionGroup>

</configSections>

</configuration>

В этот момент мы можем откомпилировать приложение и воспользоваться новым объектом параметров. Для этого нужно просто создать этот объект. А что# бы дать к нему доступ из объекта Application,  мы создадим открытое свойство эк# земпляра:

public partial class MyApp : Application { AppSettings _settings = new AppSettings(); public AppSettings Settings {

get {

return _settings;

}

}

public MyApp() {

this.Exit += MyApp_Exit;

this.Startup += AppStartup;

}

void MyApp_Exit(object sender, ExitEventArgs e) {

Settings.Save();

}

void AppStartup(object sender, StartupEventArgs args) { Window w = new Window();

w.Title = «You ran this « + (Settings.RunCount++) + « times»;

w.Show();

}

}

Если  несколько  раз запустить  это приложение, то мы увидим  окно, изобра# женное на рис. 2.6. Если давать доступ к параметрам непосредственно из объекта Application,  то любой объект в WPF#приложении сможет к ним обратиться.  Вы# зов метода Settings.Save из события Exit сохраняет  параметры  при выходе из приложения. Вызывать  Settings.Save можно  в любой  момент; Например, прог# рамма Microsoft  OneNote сохраняет  параметры  во время работы, чтобы гаранти# ровать целостность  состояния даже в случае аварийного  завершения.

Рис. 2.6. Запуск приложения с конфигурационными параметрами

Состояние, связанное с содержимым

Состояние,  связанное  с содержимым, обычно называют ресурсами (ссылки на изображения, мультимедийное содержимое,  документы  и т.д.). Оно определяет# ся на этапе разработки  программы.  WPF предоставляет для  загрузки  ресурсов несколько API, которые позволяют получить содержимое, ассоциированное с приложением.

С помощью системы конфигурирования мы можем получить доступ к состо# янию, которое сохраняется между запусками  и может быть изменено  во время выполнения. Если же речь о состоянии,  которое фиксировано во время  разра# ботки, например, о картинках или определении пользовательского интерфейса, то понадобится система управления ресурсами. В простейшем  виде для ссылки на ресурс  достаточно  указать  полный  путь  к файлу  или  URI  со схемой  http (рис. 2.7):

<!— Window1.xaml —>

<Window … >

<StackPanel Orientation=’Horizontal’>

<Image

Source=’http://blog.simplegeek.com/images/img_1476 small.png’

/>

<Image

Source=’C:\Users\Public\Pictures\Sample       Pictures\Autumn

Leaves.jpg’

/>

</StackPanel>

</Window>

Рис. 2.7. Изображения, загруженные путем задания полного пути к файлу или URI

Таблица 2.2. Типы ресурсов и способы их использования

Действие при построении

API

Можно  задавать в разметке

Что делает

Content

Application. GetContentStream

Да

Копирует  ресурс в каталог приложения.

Resource

Application. GetResourceStream

Да

Встраивает  ресурсы в общий ресурс приложения.

EmbeddedResource

Assembly. GetManifest# ResourceStream

Нет

Встраивает  ресурсы в приложение по отдельности.

Эта методика прекрасно  работает, когда нужно обращаться  к чему#то, что га# рантированно находится на машине пользователя или по указанному  URL в сети Web. Но в большинстве  случаев мы хотим сослаться на файл, находящийся в ка# кой#то папке относительно папки  приложения, или на ресурс, непосредственно встроенный в исполняемый файл.

Способов  добавить  изображение (или  любой  другой  ресурс)  в приложение хоть отбавляй.  В файле проекта MSBuild9  мы можем сконфигурировать ресурс10 как Content, Resource или EmbeddedResource11. Ресурсы  типа EmbeddedResource

 

Рис. 2.8. Структура приложения с ресурсами разных типов

<!— Window1.xaml —>

<Window … >

<StackPanel Orientation=’Horizontal’>

<!— Так будет работать —>

<Image Source=’images/content image.jpg’>

<Image Source=’images/resource image.jpg’>

<!— А так нет!! —>

<Image Source=’images/embedded image.jpg’>

</StackPanel>

</Window>

И на ресурс, описанный  в манифесте, и на скопированное содержимое  можно сослаться  из разметки,  просто указав относительный путь. К ресурсам типа EmbeddedResource напрямую из файла разметки обратиться нельзя. Но програм# мно большинство  компонентов  WPF поддерживают обращение по URI:

Image img = new Image();

img.Source = new BitmapImage(

new Uri(«images/content image.jpg», UriKind.Relative));

Любой высокоуровневый API в конечном итоге обращается к API работы с ре# сурсами,  реализованном в классе  Application.  С помощью  относительных (rela# tive) URI можно получить доступ к ресурсам, ассоциированным с приложением:

public class Application : DispatcherObject, IResourceHost {

public static StreamResourceInfo GetContentStream(Uri uriContent);

public static StreamResourceInfo GetRemoteStream(Uri uriRemote);

public    static    StreamResourceInfo     GetResourceStream(Uri uriResource);

}

Три API для доступа к ресурсам  из приложения соответствуют  трем разным логическим  хранилищам:

• GetContentStream служит   для  доступа  к  ресурсам,  заданным   в  файле проекта  с  помощью  параметра  Content. Эти  ресурсы  представлены   на диске в виде отдельных файлов.

• GetResourceStream  применяется для  доступа  к  ресурсам,  встроенным  в исполняемый файл,  то есть тем, которые  описаны  с помощью  параметра Resource.

• GetRemoteStream  можно  использовать  для  доступа   к  произвольному содержимому,   находящемуся  в  исходном   узле  приложения.  Исходный узел  – это каталог  или  Web#сервер,  откуда  было запущено  приложения. Обычно этот метод применяется для очень объемных ресурсов или таких, которые логически  отделены от самого приложения.

Источник: К. Андерсон  Основы  Windows Presentation Foundation. Пер. с англ. А. Слинкина — М.: ДМК Пресс, 2008 — 432 с.: ил.

По теме:

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