Вы зашли как: Гость
Опрос
Верите ли вы в скорый выход Surface Phone?

Начала Metro-программирования: списки и поиск файлов (ч.1)

Напечатать страницу
03.07.2012 16:33 | dronov_va

Платформа Metro, предназначенная для выполнения нового класса приложений, что доступны в Windows 8, предоставляет разработчикам богатейшие средства для создания пользовательского интерфейса и работы с данными. Они позволяют реализовать выполнение многих операций написанием буквально одного выражения, в то время как традиционным Windows-разработчикам приходилось писать для этого весьма объемный код.

Тому есть простое объяснение: операционная система Windows 8 предназначена, в том числе, и для планшетных компьютеров, а их аппаратные ресурсы по сравнению с компьютерами традиционными сильно ограничены, в том числе, ограничен и объём доступной памяти. Поэтому приложения для планшетов должны быть, по возможности, как можно более компактными, а достичь этого можно, только перенеся часть задач, которые они выполняют, на "плечи" самой операционной системы. Ведь операционная система для того и существует, чтобы выполнять по запросу приложений всевозможные типовые задачи.

Но хватит "лирики". Перейдём к прикладным вопросам. В этой статье мы изучим следующие инструменты платформы Metro:

  • Механизм прав приложений, описывающий привилегии на доступ к файловой системе и аппаратным средствам, которыми должны обладать приложения для успешного функционирования.
  • Средства для программного доступа к системным библиотекам Windows.
  • Стандартный экран выбора папки, предоставляющий пользователю возможность указать папку, содержимое которой следует обработать приложению. Этот экран аналогичен привычному нам стандартному диалоговому окну выбора папки.
  • Средства для получения списка файлов и папок, хранящихся в какой-либо папке файловой системы компьютера. В том числе платформа Metro может сформировать по нашему заказу список файлов, сгруппированных по какому-либо критерию: типу, году, месяцу, рейтингу, исполнителю композиции, альбому и др.
  • Средства для получения свойств файла: его имени, пути, размера, даты последнего изменения и др.
  • Средства для получения миниатюры файла.
  • Списки Metro - мощнейшее средство для вывода перечня каких-либо позиций (списка файлов, электронных писем, товаров в интернет-магазине и др.). Причём формат, в котором должны выводиться эти позиции, мы можем задавать произвольно, либо декларативно - в HTML-коде, описывающем интерфейс, либо программно - в коде логики.
  • Панель вывода Metro - особый элемент интерфейса, автоматически растягивающий своё содержимое, чтобы оно заняло всё пространство данного элемента.


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

  • Изначально, сразу после запуска, выводить список файлов, хранящихся в библиотеке "Изображения".
  • Давать пользователю возможность вывести содержимое произвольной папки.
  • Выводить изображение, хранящееся в выбранном пользователем файле, на экран.


Программа предстоит насыщенная, так что не расслабляемся!

Внимание!
Перед чтением следует ознакомиться с обоими статьями из цикла "Начала Metro-программирования", опубликованными на нашем сайте ранее. Описанные в них приёмы программирования будут активно здесь использоваться.


2. Начинаем создавать тестовое приложение
Запустим Visual Studio и создадим новый проект по имени ImageViewer. Сразу же откроем файл default.html, где хранится описывающий интерфейс приложения HTML-код, и вставим в парный тег <body> вот что:

<div id="divFolderPath"></div>
<div id="divViewer">
  <img id="imgViewer" />
</div>
<div id="divFileName"></div>
<div id="divList"></div>

<div id="divAppBar" data-win-control="WinJS.UI.AppBar"
data-win-options="{placement: 'top'}">
  <button data-win-control="WinJS.UI.AppBarCommand"
  data-win-options="{id: 'btnSelect', label: 'Выбрать папку', icon: 'folder', section: 'global'}"></button>
</div>

>[/code]
Этот код создаст, прежде всего, четыре блока (блочных контейнера, тега <div>), которые мы потом расположим на экране с применением сеточной разметки в направлении сверху вниз:

  • первый - divFolderPath - выведет путь к папке, указанной пользователем;
  • второй - divViewer - выведет выбранное пользователем изображение;
  • третий - divFileName - выведет имя выбранного пользователем файла;
  • четвёртый - divList - перечислит все файлы, хранязиеся в указанной пользователем папке.


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

Откроем файл default.css, где описывается оформление приложения, и создадим в нём несколько стилей, перечисленных далее.

[code]body {
display: -ms-grid;
-ms-grid-columns: 1fr;
-ms-grid-rows: 30px 1fr 40px 170px;
}[/code]
Здесь мы создаём сеточную разметку из четырёх строк, которые вместят все созданные нами блоки.

[code]#divFolderPath {
font-size: 12pt;
text-align: center;
}[/code]
Для блока divFolderPath, где будет выводиться путь к указанной папке, зададим размер шрифта, равный 12 пунктам, и выравнивание по центру.

[code]#divViewer {
-ms-grid-row: 2;
-ms-grid-column-align: center;
-ms-grid-row-align: center;
}[/code]
Для блока divViewer указываем, в том числе, выравнивание по центру. После этого выбранное пользователем изображение будет выведено в середине данного блока.

[code]#divFileName {
-ms-grid-row: 3;
font-size: 16pt;
text-align: center;
}[/code]
Для блока divFileName также задаём размер шрифта в 16 пунктов и выравнивание по центру.

[code]#divList {
-ms-grid-row: 4;
height: 170px;
}[/code]
Для блока divList указываем высоту в 170 пунктов - этого хватит, чтобы вместить список с миниатюрами изображений (как их получить, мы узнаем потом).

Сохраним все исправленные файлы...


3. Права приложения и их указание
...И рассмотрим один очень важный вопрос, являющийся ключевым в Metro-программировании и реализованной в данной платформе системе безопасности.

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

На заметку
Кстати, то же самое произойдёт, если приложение попытается прочитать содержимое подключаемого носителя (например, флэш-диска), получить данные со встроенных датчиков (GPS, электронного компаса, акселерометра и др.) или изображение с фото- или видеокамеры.

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

Чтобы всё-таки получить доступ к нужным библиотекам и устройствам, приложение должно обладать определёнными привилегиями, носящими название прав приложения. Так, если наше приложение собирается программно работать с содержимым библиотеки "Изображения", оно должно иметь право на доступ к этой библиотеке.

Права приложения задаются на этапе его разработки прямо в среде Visual Studio. Найдём в списке панели Solution Explorer файл package.appxmanifest и дважды щёлкнем на нём. В главном окне появится ещё одно окно документа, в котором наглядно, в графическом виде, будут представлены все параметры открытого нами проекта и, в частности, права приложения.

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

Здесь мы увидим список Capabilities, содержащий набор пунктов-флажков (рис. 1). Эти пункты представляют все доступные в платформе Metro права приложения; установленный флажок означает, что приложение обладает соответствующим правом, сброшенный — отменяет данное право.


Рис. 1. Содержимое вкладки Capabilities окна для задания параметров приложения


На данном этапе нам будут интересны следующие пункты списка Capabilities и соответствующие им права:

  • Document Library — доступ к библиотеке "Документы", к файлам тех типов, которые указаны в параметрах приложения;
  • Music Library — доступ к библиотеке "Музыка";
  • Pictures Library — доступ к библиотеке "Изображения";
  • Private Networks (Client & Server) — доступ к домашней сетевой группе;
  • Videos Library — доступ к библиотеке "Видео".


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

Если приложение имеет права на доступ к библиотекам "Музыка", "Изображения" или "Видео", то доступ к домашней сетевой группе предоставляется ему автоматически, и специально давать приложению такое право не требуется.

Если приложение должно иметь доступ к библиотеке "Документы", то, помимо установки флажка Document Library, нам обязательно следует указать типы файлов, которые оно сможет открывать и создавать. При этом доступ к файлам неуказанных типов будет невозможен (библиотек "Музыка", "Изображения" и "Видео" это не касается; если приложение имеет к ним доступ, оно может обрабатывать хранящиеся там файлы любых типов).

Задать сведения о доступных типах файлов можно на вкладке Declarations (рис. 2). Переключимся на неё.


Рис. 2. Содержимое вкладки Declarations окна для задания параметров приложения


Здесь мы сразу увидим список Supported Declarations, в котором перечисляются указанные нами типы файлов. Изначально он пуст.

Чтобы задать для приложения поддерживаемый тип файлов, мы выберем в раскрывающемся списке Available Declarations пункт File Type Associations и нажмём расположенную правее этого списка кнопку Add. В списке Supported Declarations появится пункт File Type Associations, представляющий вновь созданный тип. Выберем его.

В поле ввода Name, расположенном в группе элементов управления Properties, введём имя созданного типа файлов. Это имя должно содержать только строчные (маленькие) латинские буквы, цифры и знаки подчёркивания. Например, для текстовых файлов мы можем задать в качестве имени типа строку textfiles.

Ниже расположена группа элементов управления Supported File Types, в которой, в свою очередь, находится набор групп, описывающих конкретные расширения файлов, что относятся к данному типу. Расширение файла вводится в поле ввода File Type, обязательно с начальной точкой, например, .txt.

Чтобы добавить в этот набор новую группу — новое расширение файлов, следует нажать кнопку Add New. Чтобы удалить ненужную группу и, соответственно, расширение файлов, достаточно нажать присутствующую в её заголовке кнопку Remove.

Мы можем добавить в список Supported Declarations сколько угодно типов файлов и указать для каждого из них сколько угодно расширений. Так, мы можем дать приложению поддержку ещё одного типа файлов — системных (system) — с расширениями ini и log.

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

Внимание!
Если приложение использует стандартные экраны открытия и сохранения файла, его права на доступ к библиотекам указывать необязательно. Платформа Metro в этом случае будет исходить из того, что пользователь сам предоставил доступ к выбранному им в соответствующем экране файлу. Кстати, это же касается экрана выбора папки, о котором скоро пойдёт речь.


4. Получение доступа к библиотекам
Теперь, указав для приложения соответствующие права, мы можем без проблем получить доступ к системным библиотекам. Для этого достаточно воспользоваться перечислением Windows.Storage.KnownFolders, содержащим следующие элементы:

  • documentsLibrary — библиотека "Документы";
  • homeGroup — домашняя сетевая группа;
  • musicLibrary — библиотека "Музыка";
  • picturesLibrary — библиотека "Изображения";
  • videosLibrary — библиотека "Видео".


Каждый из этих элементов хранит основную папку соответствующей библиотеки. Она, как и любая другая папка файловой системы, представляется в платформе Metro в виде экземпляра объекта Windows.Storage.StorageFolder.

[code]var libImages = Windows.Storage.KnownFolders.picturesLibrary;[/code]
Получаем основную папку библиотеки "Изображения".


5. Использование стандартного экрана выбора папки
Если же наше приложение должно предоставлять пользователю возможность выбора произвольной папки, мы реализуем это с помощью стандартного экрана выбора папки. Он аналогичен привычному нам диалоговому окну выбора папки и содержит средства для указания нужной папки, список, перечисляющий все хранящиеся в открытой в данный момент папке файлы, и кнопки Выбрать папку (Pick Folder) и Отмена (Cancel).

Экран выбора папки представляется объектом Window.Storage.Pickers.FolderPicker. Мы должны создать экземпляр этого объекта и присвоить его какой-либо переменной.

[code]var oFP = new Windows.Storage.Pickers.FolderPicker();[/code]
Объект Window.Storage.Pickers.FolderPicker поддерживает уже знакомые нам свойства suggestedStartLocation, fileTypeFilter, viewMode и commitButtonText. С их помощью мы зададим параметры экрана.

[code]oFP.suggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
oFP.fileTypeFilter.replaceAll([".gif", ".jpg", ".png"]);
oFP.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;[/code]
Изначально открываем в экране выбора папки библиотеку "Изображения", перечисляем в списке файлы с расширениями gif, jpg и png (то есть графические файлы) и указываем режим вывода файлов в виде комбинаций их миниатюр и имён.

Для вывода экрана и получения выбранной в нём папки мы вызовем у него метод pickSingleFolderAsync. Этот метод не принимает параметров и возвращает в качестве результата обязательство, для которого мы с помощью метода then зададим функцию. Данная функция будет выполнена после того, как пользователь выберет папку, и в качестве единственного параметра получит:

  • либо экземпляр объекта Windows.Storage.StorageFolder, представляющий выбранную пользователем папку, если пользователь таки её выбрал;
  • либо значение null, если пользователь отказался от выбора папки.


[code]oFP.pickSingleFolderAsync().then(function(folder) {
if (folder) {
//Папка была выбрана
} else {
//Папка не была выбрана
}
});[/code]

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

5.1. Получение простого списка файлов и папок
Проще всего получить простой список содержимого папки, без сортировки и группировки. Для этого служат два метода объекта Windows.Storage.StorageFolder, который, как мы уже знаем, представляет папку:

  • getFilesAsync — получение списка всех файлов;
  • getFoldersAsync — получение списка всех папок.


Оба метода в данном случае вызываются без параметров и возвращают в качестве результата обязательство. Функция, которую мы для него укажем в вызове метода then, выполнится после завершения формирования списка файлов или папок и получит в качестве результата коллекцию, которая и представляет данный список. Это та же самая коллекция, что получается в результате вызова метода pickMultipleFilesAsync (см. описание работы с экраном открытия файла в предыдущей статье из цикла "Начала Metro-программирования"); она поддерживает свойство size и способ доступа к элементам, характерный для массивов.

[code]var arrFiles = [];
libImages.getFilesAsync().then(function(files) {
if (files.size > 0) {
for (var i = 0; i < files.size; i++) {
arrFiles.push(files);
}
}
});[/code]
Получаем список всех файлов, что хранятся в библиотеке Изображения, и помещаем эти файлы в массив arrFiles для дальнейшей обработки.

Метод push массива принимает в качестве единственного параметра значение и добавляет его в массив, у которого был вызван. Данный метод предоставляет нам простейший и быстрейший способ добавить в массив новый элемент.

5.2. Получение списка файлов с сортировкой
Получить список файлов, отсортированный по заданному критерию, немного сложнее. Мы вызовем знакомый нам метод getFilesAsync, передав ему в качестве единственного параметра один из элементов перечисления Windows.Storage.Search.CommonFileQuery, задающий критерий сортировки:

  • defaultQuery — сортировка отсутствует (поведение по умолчанию);
  • orderByName — сортировка по наименованию файла (это может быть заголовок, записанный в метаданных, или, если он отсутствует, имя файла);
  • orderByTitle — сортировка по заголовку файла, записанному в его метаданных (это может быть заголовок документа, название музыкальной композиции или фильма, тема почтового сообщения и др.). Поддерживается только для файлов, хранящихся в библиотеке или домашней сетевой группе;
  • orderByMusicProperties — сортировка по музыкальным метаданным (названию композиции и альбома, имени исполнителя и др.). Поддерживается только для файлов, хранящихся в библиотеке "Музыка" или домашней сетевой группе;
  • orderBySearchRank — сортировка сначала по рейтингу во встроенной в Windows поисковой подсистеме, а потом — по дате последнего изменения;
  • orderByDate — сортировка по дате файла (это может быть дата съёмки для файла с фотографией, дата последней правки документа, дата последнего изменения файла и др.).


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

[code]var arrFiles = [];
libImages.getFilesAsync(Windows.Storage.Search.CommonFileQuery.orderBySearchRank).then(function(files) {
if (files.size > 0) {
for (var i = 0; i < files.size; i++) {
arrFiles.push(files);
}
}
});[/code]
Получаем список всех файлов в библиотеке Изображения и вложенных в неё папках, отсортированный по их рейтингу и дате последнего изменения.

5.3. Получение списка файлов с группировкой
Несложно получить и список файлов, хранящихся в указанной папке, с группировкой по заданному нами критерию. Достаточно вызвать метод getFoldersAsync, передав ему в качестве единственного параметра один из элементов перечисления Windows.Storage.Search.CommonFolderQuery, задающий критерий группировки:

  • defaultQuery — группировка отсутствует (поведение по умолчанию);
  • groupByYear — группировка файлов по году их даты (это может быть дата съёмки для файла с фотографией, дата последней правки документа, дата последнего изменения файла и др.);
  • groupByMonth — группировка файлов по месяцу их даты;
  • groupByArtist — группировка аудиофайлов по имени исполнителя;
  • groupByAlbum — группировка аудиофайлов по названию альбома;
  • groupByAlbumArtist — группировка аудиофайлов сначала по имени исполнителя, а потом — по названию альбома;
  • groupByComposer — группировка аудиофайлов по автору произведения;
  • groupByGenre — группировка аудиофайлов по жанру;
  • groupByPublishedYear — группировка аудио- и видеофайлов по году выпуска альбома или фильма;
  • groupByRating — группировка графических, аудио- и видеофайлов по рейтингу;
  • groupByTag — группировка файлов по ключевым словам;
  • groupByAuthor — группировка файлов документов по автору;
  • groupByType — группировка файлов по наименованию их типа.


Отметим, что группировка поддерживается только для файлов, хранящихся в библиотеке или домашней сетевой группе.

Если мы зададим элемент defaultQuery, то получим "на выходе" коллекцию всех папок, хранящихся в указанной нами папке, как если бы мы вызвали метод getFoldersAsync без параметров.

Если же мы зададим любой другой элемент перечисления Windows.Storage.Search.CommonFolderQuery, то есть собственно группировку файлов, метод getFoldersAsync выдаст нам список папок, сформированных платформой Metro и существующих только в памяти компьютера (виртуальных папок). Каждая из этих папок будет соответствовать определённому значению критерия группировки и включит файлы, относящиеся к этому значению.

Для примера предположим, что в нашей библиотеке "Музыка" хранятся композиции групп "Flesh Field" и "Funker Vogt". Также предположим, что MP3-файлы с этими композициями содержат корректно заполненные теги; в противном случае ничего не выйдет. Если мы выполним группировку по имени исполнителя, то получим список из двух виртуальных папок: Flesh Field и Funker Vogt. Первая папка будет хранить файлы с композициями группы "Flesh Field", а вторая — файлы с композициями группы "Funker Vogt".

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

[code]var arrFolders = [];
libMusic.getFoldersAsync(Windows.Storage.Search.CommonFolderQuery. groupByArtist).then(function(folders) {
if (folders.size > 0) {
for (var i = 0; i < folders.size; i++) {
folders.getFilesAsync().then(function(files) {
if (files.size > 0) {
var arrFiles = [];
for (var j = 0; j < files.size; j++) {
arrFiles.push(files[j]);
}
arrFolders.push(arrFiles);
}
});
}
}
});[/code]
Получаем список файлов из библиотеки "Музыка", сгруппированный по исполнителю, и формируем на его основе массив arrFolders. Каждый элемент этого массива будет соответствовать полученной в результате группировки виртуальной папке и хранить массив файлов, которые в этой папке находятся.


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


Продолжение следует...


dronov_va, TheVista.Ru Team
Июль 2012

Комментарии

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

По теме

Акции MSFT
88.67 -0.32
Акции торгуются с 17:30 до 00:00 по Москве
Мы на Facebook
Мы ВКонтакте
Все права принадлежат © MSInsider.ru (ex TheVista.ru), 2017
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.192 секунд (Общее время SQL: 0.08 секунд - SQL запросов: 31 - Среднее время SQL: 0.00258 секунд))