Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

Начала Metro-программирования: создание настраиваемых приложений (ч.2)

Напечатать страницу
23.01.2013 10:45 | dronov_va

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

Выходит, мы должны предусмотреть какой-то способ сохранить эти настройки. Но где и как?


3.1. Хранилища настроек
Для хранения настроек приложения WinRT предлагает два специальных хранилища, которые так и называются — хранилища настроек.

  • Локальное, или непереносимое, хранилище служит для хранения настроек, которые не требуется синхронизировать между всеми устройствами, принадлежащими данному пользователю. Объём локального хранилища не ограничен.
  • Переносимое хранилище применяется для хранения настроек, которые требуется синхронизировать между устройствами. Объём переносимого хранилища ограничен и составляет 5 Мбайт.

    Внимание!
    Возможно сохранение в переносимом хранилище настроек, объём которых превышает 5 Мбайт. Однако в этом случае их синхронизация выполняться не будет.


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

Получить доступ к обоим этим хранилищам можно с помощью особого объекта Windows.Storage.ApplicationData.

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

var oAppData = Windows.Storage.ApplicationData.current;


Теперь в переменной oAppData хранится экземпляр объекта Windows.Storage.ApplicationData, представляющий "персональное" хранилище настроек данного приложения.

Объект Windows.Storage.ApplicationData поддерживает следующие свойства, позволяющие получить доступ к нужному нам хранилищу:

  • localSettings — локальное хранилище;
  • roamingSettings — переносимое хранилище.


Значением обоих этих свойств является так называемый контейнер настроек — структура, объединяющая все записанные нами данные. Он представляется экземпляром объекта Windows.Storage.ApplicationDataContainer.

var oRSC = oAppData.roamingSettings;



3.2. Сохранение настроек
Сначала рассмотрим сохранение настроек (чтобы было что потом считывать).


3.2.1. Сохранение простых значений
Проще всего сохранить в контейнере настроек какие-либо простые значения: строки, числа, логические величины, экземпляры объектов и др.

Контейнер настроек поддерживает весьма примечательное свойство values. Оно хранит пустой хэш (ассоциативный массив), в котором мы и сохраним все нужные значения. Этот хэш представляет собой экземпляр объекта, реализующего интерфейс Windows.Foundation.Collections.IPropertySet, но ведет себя так же, как обычные хэши JavaScript.

В качестве индекса сохраняемого элемента указывается строковое значение. Его длина не должна превышать 255 символов. Cохраняемое значение может быть любого типа, но его объем не должен быть более 8 Кбайт.

oRSC.values["playOnOpen"] = true;
oRSC.values["filePath"] = "c:\videos\somevideo.mp4";
oRSC.values["currentDate"] = new Date();


Сохраняем в контейнере, соответствующем переносимому хранилищу, логическое значение, строку и экземпляр объекта Date, представляющий текущую дату.

Ещё хэш, хранящийся в свойстве values контейнера, поддерживает несколько полезных для нас методов и одно свойство. Давайте поговорим о них.

Метод remove позволяет удалить не нужный более элемент. В качестве единственного параметра он принимает строку с индексом удаляемого элемента и не возвращает результата.

oRSC.values.remove("currentDate");


Метод clear удаляет все элементы из хэша. Он не принимает параметров и не возвращает результата.

oRSC.values.clear();


Метод hasKey позволяет узнать, присутствует ли в хэше элемент с указанным индексом. В качестве единственного параметра он принимает строку с искомым индексом и возвращает true, если таковой элемент присутствует в контейнере, и false, если его там нет.

if (oRSC.values.hasKey("filePath")) {
  //Элемент с таким индексом существует
}

сом существует
}[/code]
А свойство size возвращает количество элементов в хэше.

[code]var iSettingCount = oRSC.values.size;[/code]

3.2.2 Создание составных значений
Иногда требуется сохранить сразу несколько значений в составе единой структуры данных. В таком случае мы создадим составное значение и поместим все сохраняемые значения настроек в него.

Составное значение представляется объектом Windows.Storage.ApplicationDataCompositeValue. Нам следует создать экземпляр этого объекта.

[code]var oCV = new Windows.Storage.ApplicationDataCompositeValue();[/code]
Составное значение ведёт себя как хэш. Следовательно, для помещения в него значений мы можем использовать знакомые приёмы.

[code]oCV["playOnOpen"] = true;
oCV["rewindOnEnd"] = false;[/code]
Сохраняем в составном значении две логические величины.

Важно помнить, что совокупный объём всех значений, хранящихся в составном значении, не должен превышать 64 Кбайт.

Готовое составное значение мы можем сохранить в контейнере, как проделывали это с простыми значениями.

[code]oRSC.values["playerSettings"] = oCV;[/code]
Составное значение поддерживает уже знакомые нам методы remove, clear и hasKey и свойство size.


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

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

Создание вложенного контейнера выполняется вызовом метода createContainer основного контейнера.

[code]<основной контейнер>.createContainer(
<имя вложенного контейнера>,
<следует ли создавать вложенный контейнер>
)[/code]
Первым параметром передаётся уникальное имя создаваемого вложенного контейнера в виде строки. Вторым параметром указывается один из элементов перечисления Windows.Storage.ApplicationDataCreateDisposition, указывающий, следует ли создавать данный контейнер, если он не существует:

  • always — если контейнер с указанным именем не существует, он будет создан; в противном случае будет возвращён существующий контейнер;
  • existing — возвращается уже существующий контейнер с указанным именем; если же такого контейнера нет, он не будет создан.


Метод createContainer возвращает вложенный контейнер — либо созданный, либо уже существующий. Он представляется экземпляром объекта Windows.Storage.ApplicationDataContainer — того же, что и основной контейнер. Если мы указали, чтобы несуществующий контейнер не создавался, и такого контейнера нет, будет возвращено значение null.

[code]var oC = oRSC.createContainer("playerSettings",
Windows.Storage.ApplicationDataCreateDisposition.always);[/code]

Получив вложенный контейнер, мы заполним его сохраняемыми данными.

[code]oC.values["playOnOpen"] = false;
oC.values["rewindOnEnd"] = false;[/code]
Сохраняем во вложенном контейнере строковое и логическое значения.

Мы можем сохранить во вложенном контейнере составные значения и даже создать в нём другие вложенные контейнеры. Выполняется это так же, как и в случае с основным контейнером.

Любой контейнер поддерживает свойство containers. Оно хранит экземпляр особого объекта-коллекции, реализующего интерфейс Windows.Foundation.Collections.IMapView и перечисляющей все вложенные контейнеры, что хранятся в данном контейнере. Этот объект предоставляет нам два метода и свойство, которые могут нам пригодиться.

Метод hasKey нам уже знаком. Он позволяет узнать, существует ли вложенный контейнер с указанным именем.

[code]if (oRSC.containers.hasKey("playerSettings")) {
//Вложенный контейнер playerSettings существует
}[/code]
Метод lookup позволяет получить вложенный контейнер с указанным именем. Имя нужного контейнера передается единственным параметром в виде строки.

[code]if (oRSC.containers.hasKey("playerSettings")) {
var oC = oRSC.containers.lookup("playerSettings");
oC.values["playOnOpen"] = false;
oC.values["rewindOnEnd"] = false;
}[/code]
Свойство size возвращает количество вложенных контейнеров.

Если нам потребуется удалить ненужный вложенный контейнер, мы вызовем метод deleteContainer; вызывать его следует у того контейнера, в который вложен удаляемый контейнер. Данный метод принимает в качестве единственного параметра строку с именем удаляемого контейнера и не возвращает результата.

[code]oRSC.deleteContainer("playerSettings");[/code]

3.3. Считывание настроек

Прочитать сохранённые ранее настройки очень просто.

[code]var oAppData = Windows.Storage.ApplicationData.current;
var oRSC = oAppData.roamingSettings;
var bPlayOnOpen = oRSC.values["playOnOpen"];
var sFilePath = oRSC.values["filePath"];
var dCurrentDate = oRSC.values["currentDate"];[/code]
Считываем значения трёх элементов, хранящихся непосредственно в основном контейнере.

Если мы попытаемся прочитать значение по несуществующему индексу, мы получим null.

[code]var bShowProgress = oRSC.values["showProgress"];[/code]
Элемент с индексом showProgress не существует, поэтому переменная bShowProgress получит значение null.

Для проверки существования элемента в контейнере можно использовать метод hasKey, описанный ранее.

[code]var oCV = oRSC.values["playerSettings"];
if (oCV) {
var bPlayOnOpen = oCV["playOnOpen"];
var bRewindOnEnd = oCV["rewindOnEnd"];
}[/code]
Извлекаем из контейнера составное значение и, если оно существует, получаем хранящиеся в нём данные.

[code]if (oRSC.containers.hasKey("playerSettings")) {
var oC = oRSC.containers.lookup("playerSettings");
var bPlayOnOpen = oCV["playOnOpen"];
var bRewindOnEnd = oCV["rewindOnEnd"];
}[/code]
Получаем настройки, хранящиеся во вложенном контейнере.


3.4. Отслеживание изменения настроек, сохранённых в переносимом хранилище
Как только мы записываем какое-либо значение в переносимое хранилище настроек, в экземпляре объекта Windows.Storage.ApplicationData возникает событие datachanged. Это событие следует использовать для того, чтобы перенести новые значения настроек данного приложения на все остальные его копии, установленные на других компьютерах, что принадлежат этому же пользователю.

[code]var oAppData = Windows.Storage.ApplicationData.current;
oAppData.addEventListener("datachanged", function() {
var oRSC = oAppData.roamingSettings;
var bPlayOnOpen = oRSC.values["playOnOpen"];
var sFilePath = oRSC.values["filePath"];
var dCurrentDate = oRSC.values["currentDate"];
});[/code]
Благодаря этому мы можем быть уверены, что все копии приложения, установленные на всех компьютерах, используют одни и те же настройки.


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

Откроем в Visual Studio проект VideoPlayer, если уже его закрыли. Сразу переключимся на файл default.js, где пишется код логики.

Объявим ещё одну переменную:

[code]var oRSC = Windows.Storage.ApplicationData.current.roamingSettings;[/code]
Она будет хранить переносимое хранилище настроек для данного приложения.

Отыщем код инициализации и дополним его следующими выражениями (выделены комментариями):

[code]document.addEventListener("DOMContentLoaded", function() {
WinJS.UI.processAll().then(function() {
. . .

vidMain.volume = 0.5;

//Вставленный код - начало

var oAppData = Windows.Storage.ApplicationData.current;
oAppData.addEventListener("datachanged", appDataDataChanged);
appDataDataChanged();

//Вставленный код - конец
});
});[/code]
Здесь мы привязываем к хранилищу настроек обработчик события datachanged и сразу же вызываем его, чтобы, собственно, загрузить сохранённые ранее настройки.

Напишем этот обработчик события:

[code]function appDataDataChanged() {
if (oRSC.values.hasKey("playOnOpen")) {
bPlayOnOpen = oRSC.values["playOnOpen"];
}
if (oRSC.values.hasKey("rewindOnEnd")) {
bRewindOnEnd = oRSC.values["rewindOnEnd"];
}
}[/code]
Он будет считывать сохранённые настройки, если, конечно, они были сохранены.

И дополним обработчики события change обоих переключателей кодом, который будет сохранять настройки:

[code]function tglPlayOnOpenChange() {
bPlayOnOpen = tglPlayOnOpen.checked;
oRSC.values["playOnOpen"] = bPlayOnOpen;
}
function tglRewindOnEndChange() {
bRewindOnEnd = tglRewindOnEnd.checked;
oRSC.values["rewindOnEnd"] = bRewindOnEnd;
}[/code]
Всё! Осталось сохранить исправленные файлы и проверить приложение в действии.


Дополнительные материалы



dronov_va, TheVista.Ru Team
Январь 2013

Комментарии

Комментариев нет...
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.038 секунд (Общее время SQL: 0.015 секунд - SQL запросов: 51 - Среднее время SQL: 0.00029 секунд))
Top.Mail.Ru