Главная » Разработка для Windows Phone 7 » Jot и параметры приложения

0

Приложение Jot (Записка), которое будет рассмотрено следующим – это одно из трех приложений данной главы, которое может быть полезным в повседневной жизни. Его идея возникла из приложения QuickNotes, которое также будет описано в данной главе несколько позже. По сути QuickNotes – это большой элемент TextBox, но содержимое этого TextBox хранится изолированном хранилище. Мы можем добавлять и удалять текст из него, но каждый раз, открывая это приложение, мы получаем текст, который оставили в нем в предыдущий раз. Данное приложение замечательно подходит для коротких заметок (как предполагает его название), потому что пользователю не приходится загружать или сохранять файлы, все делается автоматически.

Но обсудим QuickNotes более подробно в конце этой главы. А сейчас обратимся к аналогичному и более простому в использовании приложению Jot. Для работы с ним не требуется ни виртуальной, ни реальной клавиатуры, вводить текст или рисовать можно просто с помощью пальца.

Как будет показано, в QuickNotes все реализовано с использованием одного единственного текстового документа, и пользователь может без труда прокручивать его и вводить текст в любом месте. Приложение Jot использует элементы Canvas, и их фиксированный размер, кажется, подразумевает, что приложение должно поддерживать множество страниц для множества холстов.

Отображение сенсорного ввода в Jot реализовано с помощью класса InkPresenter, который берет начало с интерфейсов для планшетных ПК. InkPresenter наследуется от панели Canvas, что означает возможность использования его свойства Children для создания фонового изображения (традиционной желтой блокнотной странички, например). Или можно полностью игнорировать все возможности InkPresenter, обеспечиваемые происхождением от Canvas.

Главное назначение InkPresenter – отображение рукописного ввода, который он представляет как множество серий соединенных коротких линий – полилиний, если говорить на языке графики, или в данном контексте мы называем их обводками.

Точка на поверхности экрана описывается классом StylusPoint (Штрих стилуса) – это структура, определенная в пространстве имен System.Windows.Input и имеющая свойства X и Y, а также PressureFactor (Коэффициент нажима) для устройств, поддерживающих распознавание силы нажима (Windows Phone 7 не поддерживает этого).

Проводя по экрану пальцем (на сенсорных экранах) или стилусом (на планшетных ПК), можно создать множество кривых абсолютно невообразимых форм. Но независимо от того насколько запутанны кривые, они всегда представляются коллекцией объектов StylusPoint, которые в совокупности повторяют сложную кривую. Коллекция объектов StylusPoint, представляющих непрерывную линию, инкапсулируется в Stroke. Это класс из пространства имен System.Windows.Ink. Объект Stroke инкапсулирует не только точки кривой, но также ее цвет и толщину. Для этого в нем предусмотрены следующие два свойства:

•           StylusPoints (Штрихи стилуса) типа StylusPointCollection (Коллекция штрихов стилуса)

•           DrawingAttributes (Атрибуты рисования) типа DrawingAttributes

Stroke – это непрерывная линия, которая создается, когда пользователь касается экрана, повторяет все движения пальца по нему и завершается, когда пользователь отрывает палец от экрана. Со следующим касанием экрана создается другой Stroke. Множество объектов Stroke хранится в StrokeCollection (Коллекция обводок). Именно они и хранятся в объекте InkPresenter: InkPresenter описывает свойство Strokes типа StrokeCollection и формирует визуальное представление этих обводок, которые все вместе образуют непрерывную кривую.

Приложение Jot многостраничное, поэтому ему понадобится еще одна отдельная коллекция для хранения объектов StrokeCollection для каждой из страниц.

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

Параметры приложения для Jot инкапсулированы в специально предназначенный для этих целей класс JotAppSettings (Параметры приложения Jot). Экземпляр JotAppSettings сериализуется и сохраняется в изолированном хранилище. Этот класс также имеет методы для сохранения и загрузки параметров. В проект необходимо включить ссылку на библиотеку System.Xml.Serialization; в JotAppSettings требуется несколько нестандартных директив using для System.Collection.Generic, System.IO, System.IO.IsolatedStorage и System.Xml.Serialization.

Рассмотрим открытые свойства JotAppSettings, составляющие параметры приложения: Проект Silverlight: Jot Файл: JotAppSettings.cs (фрагмент)

public List<StrokeCollection> StrokeCollections { get; set; }

public int PageNumber { set; get; }

public Color Foreground { set; get; }

public Color Background { set; get; }

public int StrokeWidth { set; get; }

Для каждой страницы Jot отображает один StrokeCollection, таким образом, приложению необходимо хранить коллекцию объектов StrokeCollection. Приложение начинает выполнение со страницы, обозначенной PageNumber (Номер страницы).

При первом запуске Jot выбирает цвета Foreground и Background из темы системы. Но при этом приложение реализует возможность изменения этих цветов для целей рисования, предполагая, что пользователь может предпочесть тему «белое на черном» для телефона в целом, но «черное на белом» для Jot. Поэтому приложение сохраняет и загружает цвета явно. По умолчанию свойство StokeWidth (Толщина обводки) имеет значение 3 (значение по умолчанию для InkPresenter), но пользователь может изменить его и задать 1 или 5.

Для сохранения этих элементов я попытался использовать класс IsolatedStorageSettings, но у меня ничего не получилось, поэтому я обратился к традиционному изолированному хранилищу. Рассмотрим метод Save:

Проект Silverlight: Jot Файл: JotAppSettings.cs (фрагмент)

public void Save() {

IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication(); IsolatedStorageFileStream stream = iso.CreateFile("settings.xml"); StreamWriter writer = new StreamWriter(stream);

XmlSerializer ser = new XmlSerializer(typeof(JotAppSettings)); ser.Serialize(writer, this);

writer.Close(); iso.Dispose();

}

Метод Save создает (или воссоздает) в изолированном хранилище файл settings.xml, получает StreamWriter (Модуль записи в поток), ассоциированный с этим файлом, и затем использует класс XmlSerializer для сериализации этого конкретного экземпляра класса JotAppSettings.

Метод Load является статическим, потому что должен создавать экземпляр JotAppSettings путем десериализации файла из хранилища. Если этого файла не существует – это означает, что приложение выполняется впервые – он просто создает новый экземпляр.

Проект Silverlight: Jot Файл: JotAppSettings.cs (фрагмент)

public static JotAppSettings Load() {

JotAppSettings settings;

IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();

if (iso.FileExists("settings.xml")) {

IsolatedStorageFileStream stream = iso.OpenFile("settings.xml",

FileMode.0pen);

StreamReader reader = new StreamReader(stream);

XmlSerializer ser = new XmlSerializer(typeof(JotAppSettings)); settings = ser.Deserialize(reader) as JotAppSettings;

reader.Close();

}

else {

// Создаем и инициализируем новый объект JotAppSettings settings = new JotAppSettings();

settings.StrokeCollections = new List<StrokeCollection>(); settings.StrokeCollections.Add(new StrokeCollection());

}

iso.Dispose(); return settings;

}

Конструктор класса задает для некоторых (но не всех) свойств значения по умолчанию: Проект Silverlight: Jot Файл: JotAppSettings.cs (фрагмент)

public JotAppSettings() {

this.PageNumber = 0;

this.Foreground = (Color)Application.Current.Resources["PhoneForegroundColor"]; this.Background = (Color)Application.Current.Resources["PhoneBackgroundColor" ]; this.StrokeWidth = 3;

}

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

Изначально я тоже создавал коллекцию StrokeCollection в конструкторе:

settings.StrokeCollections = new List<StrokeCollection>(); settings.StrokeCollections.Add(new StrokeCollection());

Но обнаружилось, что в этом случае метод Deserialize (Десериализовать) класса XmlSerializer не создает новый объект List, а просто использует тот, который был создан в конструкторе, из-за чего я оставался с одним новым пустым StrokeCollection в List при каждом выполнении приложения! Поэтому я перенес этот код в метод Load.

Методы Save и Load класса JotAppSettings вызываются только из App.xaml.cs в ходе обработки четырех событий PhoneApplicationService, обсуждаемых нами в главе 6. Эти события сигнализируют о запуске, деактивации, активации и завершении приложения. App.xaml.cs также предоставляет параметры приложения как открытое свойство:

Проект Silverlight: Jot Файл: App.xaml.cs (фрагмент)

public partial class App : Application {

// Параметры приложения

public JotAppSettings AppSettings { set; get; }

private void Application Launching(object sender, LaunchingEventArgs e) AppSettings = JotAppSettings.Load();

private void Application_Activated(object sender, ActivatedEventArgs e) AppSettings = JotAppSettings.Load();

private void Application_Deactivated(object sender, DeactivatedEventArgs e) AppSettings.Save();

private void Application Closing(object sender, ClosingEventArgs e) AppSettings.Save();

}

В рамках MainPage все ссылки на свойства, составляющие параметры приложения, выполняются через свойство AppSettings класса App.

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

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