Текст книги "Программирование мобильных устройств на платформе .NET Compact Framework"
Автор книги: Иво Салмре
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 45 (всего у книги 69 страниц)
Растровые изображения с масками прозрачности полезны по многим причинам. При написании игр растровые изображения с областями прозрачности могут использоваться разработчиками для вывода на экран игрового поля и перемещения по нему изображений, форма которых не является прямоугольной. В картографических приложениях растровые изображения с масками прозрачности могут использоваться для вывода изображений поверх карт, генерируемых другими источниками; в качестве хорошего примера можно привести отображения на карте маркера, отмечающего текущее местоположение объекта. Наконец, встраивание изображений непрямоугольной формы в другую графику может с успехом использоваться для создания привлекательных пользовательских интерфейсов и бизнес-графики.
Растровые изображения, или битовые образы, являются, по сути, двумерными массивами целых чисел, где каждое число представляет цвет пикселя в определенной точке. В силу этого растровые изображения по самой своей природе имеют прямоугольную форму. Представление не являющегося прямоугольным изображения на прямоугольной битовой карте можно обеспечить, объявляя один цвет фоновым и заполняя пиксели, лежащие за пределами интересующего нас непрямоугольного изображения, этим цветом. Работа с правильными прямоугольными массивами обладает целым рядом преимуществ, не самым последним из которых является легкость копирования части одного изображения на часть другого; в случае прямоугольных областей для этого требуются самые простые алгоритмы. В результате копирования прямоугольной части одного растрового изображения на другое происходит простая замена информации об изображении, относящейся к соответствующей прямоугольной области. Это означает, что прямоугольные битовые карты, содержащие непрямоугольные изображения с единственным цветом фона, копируются в место назначения в виде непрозрачных прямоугольников изображений переднего и заднего планов. Результат выглядит совсем не привлекательно. В качестве альтернативного решения можно исходить из фонового изображения и создать на нем рисунок всех непрямоугольных изображений, используя функции рисования (например, DrawLine(), FillCircle()) или устанавливая пиксельные данные по одному пикселю за один раз. Оба эти способа приводят к хорошим визуальным результатам, но работают медленно и требуют написания сложных функций. Что нам необходимо сделать – так это скопировать одно растровое изображения на другое, не копируя фоновый цвет.
На рис. 13.10 представлено простое растровое изображение для игры; битовая карта является прямоугольной, но само изображение, которое мы хотим нарисовать – нет. Чтобы нарисовать это изображение без его прямоугольного фона, мы должны сообщить функции, осуществляющей копирование, о том, что копировать пиксели, цвет которых совпадает с установленным нами фоновым цветом, не следует. В .NET Compact Framework это достигается за счет использования класса ImageAttributes.
Класс ImageAttributes имеет метод SetColorKey(), используя который ваш код может устанавливать цвет маскирования. Указанный класс может передаваться в качестве параметра в одну из перегруженных версий функции Graphics.DrawImage(); получение этого параметра поддерживается только одной из перегруженных версий этой функции.
Функция DrawImage() получает в качестве параметров исходную битовую карту изображения, которое мы хотим копировать, размеры и местоположения областей, из которых и в которые должно осуществляться копирование, и объект ImageAttributes, указывающий, какая цветовая маска будет определять прозрачность в исходном изображении. Далее, на битовую карту назначения копируется информация обо всех пикселях исходного растрового изображения за исключением тех, цвет которых согласуется с цветом маски, определенным в объекте ImageAttributes.
Пиксели исходного растрового изображения, которые имеют тот же цвет, что и маска, не копируются. Благодаря этому существовавшие до этого пиксели изображения назначения "проступают" сквозь прозрачные области той битовой карты, которую мы копируем. Такая операция копирования выполняется медленнее, чем простое копирование прямоугольного изображения, но все же достаточно быстро, что делает этот вариант привлекательным при работе с непрямоугольными изображениями.

Рис. 13.10. Простое растровое изображение с передним планом непрямоугольной формы и одноцветным фоном
Если известно, что необходимость в рисунках возникнет вновь или будет возникать регулярно, то имеет смысл глобально кэшировать объект ImageAttributes, который может использоваться по всему приложению в вашем коде рисования изображений неправильной формы с прозрачным фоном; это избавит вас от необходимости многократно распределять память для объектов ImageAttributes, а затем освобождать ее, и избавит от накопления "мусора" в памяти вашего приложения.
Пример использования растровых изображений с областями прозрачности
На рис. 13.11 показан пример того, как использование прозрачных областей дает возможность получать изображения, отвечающие повышенным запросам. На первом из снимков представлено изображение заднего плана. В данном случае оно состоит из черного текста на белом фоне. На втором снимке представлено другое изображение, в качестве которого используются графические объекты в виде синего фона с нарисованными поверх него прямоугольником и двумя эллипсами желтого цвета. На третьем снимке показано второе изображение, нарисованное поверх первого, но с использованием желтого цвета в качестве прозрачного. Результат таков, что когда второе изображение копируется на первое, то все пиксели желтого цвета не копируются, в результате чего исходные пиксели первого изображения, находящиеся в соответствующих позициях, видны в конечном изображении.

Рис. 13.11. Приложение, иллюстрирующее процесс рисования с использованием прозрачного фона
Приложение, представленное на рис. 13.11, можно создать с помощью кода, приведенного в листинге 13.5. Для создания и запуска приложения потребуется выполнить перечисленные ниже действия:
1. Запустите Visual Studio .NET (2003 или более позднюю версию) и выберите в качестве типа приложения C# Smart Device Application.
2. Выберите в качестве целевой платформы Pocket PC. (Для вас будет автоматически создан проект, и на экране появится окно конструктора форм Pocket PC.)
3. Добавьте в форму элемент управления Button (ему будет присвоено имя button1) и переименуйте его в buttonDrawBackground.
4. Дважды щелкните на кнопке в окне конструктора форм и введите для нее код функции buttonDrawBackground_Click(), листинг которой приводится ниже.
5. Добавьте в форму элемент управления Button и переименуйте его в buttonDrawForeground.
6. Дважды щелкните на кнопке в окне конструктора форм и введите для нее код функции buttonDrawForeground_Click(), листинг которой приводится ниже.
7. Вернитесь к форме Form1 в окне конструктора форм.
8. Добавьте в форму элемент управления Button и переименуйте его в buttonDrawBackgroundPlusForeground.
9. Дважды щелкните на кнопке в окне конструктора форм и введите для нее код функции buttonDrawBackgroundPlusForeground_Click(), листинг которой приводится ниже.
10. Введите оставшуюся часть кода, приведенного в листинге ниже.
11. Вернитесь в окно конструктора форм.
12. Установите для свойства MinimizeBox формы значение false. Благодаря этому во время выполнения в верхней правой части формы появится кнопка OK, с помощью которой вы легко сможете закрыть форму и выйти из приложения. Эта возможность оказывается очень полезной при многократном тестировании приложения
13. Полученные вами результаты должны воспроизводить те, которые показаны на рис. 13.11.
Дополнительные эффекты с использованием прозрачных изображений
Выбор желтого цвета в качестве прозрачного был сделан совершенно произвольно. Точно так же в качестве прозрачного цвета можно было выбрать синий цвет и позволить скопироваться в изображении переднего плана всему, что имеет желтый цвет, а синий цвет трактовать как прозрачный. Кроме того, не сложно поменять местами битовые карты переднего и заднего планов, сделав желтые и синие прямоугольники и эллипсы задним планом, а черный и белый текст – передним; в этом случае нам потребовалось бы выбрать в качестве прозрачного черный или белый цвет, и, в зависимости от нашего решения, прозрачными были бы либо текст, либо его фон. Прозрачность – мощная штука, и ее можно с большим успехом применять в растровых изображениях самых различных видов.
Листинг 13.5. Код формы, демонстрирующий использование прозрачности
//–
//Размеры наших битовых образов и экранного изображения PictureBox
//–
const int bitmap_dx = 200;
const int bitmap_dy = 100;
//–
//Создает и прорисовывает изображение заднего плана
//–
System.Drawing.Bitmap m_backgroundBitmap;
void CreateBackground() {
if (m_backgroundBitmap == null) {
m_backgroundBitmap =new Bitmap(bitmap_dx, bitmap_dy);
}
//Делаем битовую карту белой
System.Drawing.Graphics gfx;
gfx = System.Drawing.Graphics.FromImage(m_backgroundBitmap);
gfx.Clear(System.Drawing.Color.White);
//Рисуем текст черным
System.Drawing.Brush myBrush;
myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
for (int у = 0; у < bitmap_dy; у = у + 15) {
gfx.DrawString("I am the BACKGROUND IMAGE...hello", this.Font, myBrush, 0, у);
}
//Очистить
myBrush.Dispose();
gfx.Dispose();
}
//–
//Создает и прорисовывает изображение заднего плана
//–
System.Drawing.Bitmap m_foregroundBitmap;
void CreateForeground() {
if (m_foregroundBitmap == null) {
m_foregroundBitmap = new Bitmap(bitmap_dx, bitmap_dy);
}
//Делаем всю битовую карту синей
System.Drawing.Graphics gfx;
gfx = System.Drawing.Graphics.FromImage(m_foregroundBitmap);
gfx.Clear(System.Drawing.Color.Blue);
//Рисуем несколько фигур желтым
System.Drawing.Brush yellowBrush;
yellowBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Yellow);
gfx.FillEllipse(yellowBrush, 130, 4, 40, 70);
gfx.FillRectangle(yellowBrush, 5, 20, 110, 30);
gfx.FillEllipse(yellowBrush, 60, 75, 130, 20);
//Очистить
yellowBrush.Dispose();
gfx.Dispose();
}
//–
//Устанавливает размеры и местоположение PictureBox с левой стороны
//–
private void SetPictureBoxDimensions() {
pictureBox1.Width = bitmap_dx;
pictureBox1.Height = bitmap_dy;
pictureBox1.Left = 20;
}
//–
//ОБРАБОТЧИК СОБЫТИЙ: Отобразить изображение ЗАДНЕГО ПЛАНА в PictureBox
//–
private void buttonDrawBackground_Click(object sender, System.EventArgs e) {
SetPictureBoxDimensions();
CreateBackground();
pictureBox1.Image = m_backgroundBitmap;
}
//–
//ОБРАБОТЧИК СОБЫТИЙ: Отобразить изображение ПЕРЕДНЕГО ПЛАНА в PictureBox
//–
private void buttonDrawForeground_Click(object sender, System.EventArgs e) {
SetPictureBoxDimensions();
CreateForeground();
pictureBox1.Image = m_foregroundBitmap;
}
//–
//ОБРАБОТЧИК СОБЫТИЙ: Наложить изображение ПЕРЕДНЕГО ПЛАНА на изображение
// ЗАДНЕГО ПЛАНА. Использовать МАСКУ ПРОЗРАЧНОСТИ, чтобы желтый
// цвет в изображении ПЕРЕДНЕГО ПЛАНА стал прозрачным и через
// него можно было видеть содержимое изображения
// ЗАДНЕГО ПЛАНА
//–
private void buttonDrawBackgroundPlusForeground_Click(object sender, System.EventArgs e) {
SetPictureBoxDimensions();
CreateForeground();
CreateBackground();
//Получить объект Graphics изображения ЗАДНЕГО ПЛАНА, поскольку
//именно поверх него мы собираемся рисовать. System.Drawing.Graphics gfx;
gfx = System.Drawing.Graphics.FromImage(m_backgroundBitmap);
//–
//Создать класс ImageAttributes. Этот класс позволяет нам
//задать прозрачный цвет на наших операций рисования
//–
System.Drawing.Imaging.ImageAttributes trasparencyInfo = new System.Drawing.Imaging.ImageAttributes();
//–
//Задать прозрачный цвет
//–
trasparencyInfo.SetColorKey(System.Drawing.Color.Yellow, System.Drawing.Color.Yellow);
//Задать прямоугольник рисунка
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, m_backgroundBitmap.Width, m_backgroundBitmap.Height);
//–
//Нарисовать изображение ПЕРЕДНЕГО ПЛАНА поверх изображения ЗАДНЕГО ПЛАНА
//и использовать прозрачный цвет в ImageAttributes для создания окна
//прозрачности, через которое виден задний план
//–
gfx.DrawImage(m_foregroundBitmap, rect, 0, 0, m_foregroundBitmap.Width,
m_foregroundBitmap.Height, System.Drawing.GraphicsUnit.Pixel, trasparencyInfo);
//Очистить
gfx.Dispose();
//Показать результат в виде растрового изображения
pictureBox1.Image = m_backgroundBitmap;
}
Во многих приложениях растровые изображения используются для того, чтобы предоставить пользователям красочный интерфейс. Нестандартные кнопки с нарисованными поверх них изображениями, графические изображения, используемые в иллюстративной графике, логотипы и другие изображения заднего плана – все это улучшает визуальный облик мобильного приложения. Вместо того чтобы заново создавать сложные рисунки, в играх интенсивно используют заранее заготовленные изображения. Поэтому очень часто удобно иметь изображения, встроенные в двоичный код приложения. Далее эти изображения автоматически развертываются вместе с приложением; такая практика гораздо более надежна, чем работа с множеством файлов изображений наряду с файлом приложения. Встраивание изображений не сопровождается увеличением общего размера приложения по сравнению с использованием отдельных файлов; в обоих случаях мы имеем дело с бинарными потоками изображений, к которым ваше приложение получает доступ по мере необходимости.
Чтобы использовать двоичные ресурсы, встроенные в приложение, вам необходимо следующее:
1. Изображения должны быть скомпилированы и включены в состав вашего приложения. Это можно указать во время проектирования в среде разработки.
2– Ваше приложение должно знать, где найти ресурсы во время выполнения. Для обращения к двоичным ресурсам, встроенным в откомпилированные сборки .NET, используется синтаксис, аналогичный путям доступа к файлам, позволяющий указывать местоположение ресурсов в загруженных сборках вашего приложения во время выполнения.
Далее мы остановимся на обоих этих моментах.
Как встроить изображение в приложение
В Visual Studio .NET процесс включения двоичных ресурсов в приложение осуществляется сравнительно несложно:
1. Запустите Visual Studio .NET.
2. Создайте проект C# Smart Device Application.
3. Выберите в меню Project (Проект) команду Add Existing ltem (Добавить существующий элемент).
4. В открывшемся диалоговом окне Add Existing Item измените установку фильтра Files of Type (Тип файлов) на Image Files (Файлы изображений).
5. Найдите файл изображения, который вы хотите добавить, и выделите его. (Примечание. Я настоятельно рекомендую выбирать файлы размером менее 300 Кбайт, иначе вы будете создавать в своем приложении гигантские файлы изображений, которые по своим размерам, скорее всего, будут превышать само приложение; растровые изображения с чрезмерно большим разрешением могут приводить к нехватке памяти устройства при их загрузке во время выполнения.) В данном примере мы будем полагать, что загружается файл MyImage.PNG.
6. Перейдя в окно Visual Studio .NET Solution Explorer, выделите только что добавленный файл изображения (MyImage.PNG), щелкните на нем правой кнопкой мыши и выберите в открывшемся контекстном меню пункт Properties (Свойства).
7. В открывшемся диалоговом окне Properties найдите свойство Build Action (Действие при сборке). По умолчанию для него устанавливается значение Content (Содержимое); это означает, что файл изображения будет копироваться на устройство вместе с приложением при его развертывании.
8. Измените значение свойства Build Action на Embedded Resource (Встроенный ресурс); это означает, что двоичное содержимое файла MyImage.PNG будет встраиваться в исполняемый образ приложения всякий раз, когда оно будет компилироваться.
Имена встроенных ресурсов чувствительны к регистру
Независимо от того, чувствителен ли к регистру используемый вами язык программирования (для C# регистр имеет значение, для VB.NET – нет), в именах встроенных ресурсов строчные и прописные буквы различаются. Тщательно следите за правильным использованием регистра букв в именах файлов, которые вы делаете встроенными ресурсами; при поиске потоков ресурсов во время выполнения ваше приложение будет использовать буквы в том же регистре, в котором вы их указали. Если потоки ресурсов не удается найти из-за несовпадения имен, то во время выполнения генерируется исключение. Ошибки подобного рода являются распространенными, и их поиск может заставить вас понервничать, если вы не знаете о том, что надо сразу же проверять, правильно ли указаны регистры букв.
Как получить доступ к встроенному ресурсу приложения
Приведенный в листинге 13.6 код демонстрирует, как загрузить растровое изображение из потока встроенного ресурса в ваше приложение. В соответствии с предыдущим изложением в качестве изображения для примера используется файл MyImage.PNG. Этот код следует поместить в форму с элементами управления Button и PictureBox. Как и в предыдущих примерах, для подключения события button1_click к кнопке button1 следует дважды щелкнуть на кнопке в окне конструктора форм, в результате чего будет автоматически сгенерирован костяк функции.
Листинг 13.6. Код формы, демонстрирующий загрузку встроенных ресурсов
System.Drawing.Bitmap m_myBitmapImage;
//–
//Загрузить изображение, которое хранится в виде встроенного ресурса
//в нашей сборке
//–
public void LoadImageFromResource() {
//Если изображение уже загружено,
//то не имеет смысла делать это повторно.
if (m_myBitmapImage !=null) {
return;
}
//–
//Получить ссылку на двоичную сборку нашего приложения
//–
System.Reflection.Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
//–
//Получить имя сборки
//–
System.Reflection.AssemblyName thisAssemblyName = thisAssembly.GetName();
string assemblyName = thisAssemblyName.Name;
//–
//Извлечь поток изображения из нашей сборки и создать соответствующую
//ему битовую карту в памяти.
//ПРИМЕЧАНИЕ: Имя потока ресурса ResourceStream ЧУВСТВИТЕЛЬНО К РЕГИСТРУ,
// поэтому имя изображения должно В ТОЧНОСТИ совпадать с именем
// файла изображения, который вы добавили в проект
//–
m_myBitmapImage = new System.Drawing.Bitmap(thisAssembly.GetManifestResourceStream(assemblyName + ".MyImage.PNG"));
}
//–
//Загрузить изображение и отобразить его в объекте PictureBox
//–
private void button1_Click(object sender, System.EventArgs e) {
LoadImageFromResource();
pictureBox1.Image = m_myBitmapImage;
}
Форматы хранения изображений и прозрачность растровых изображений
При использовании изображений в приложении очень важно правильно выбрать для них формат хранения. Для крохотных битовых образов (например, 8×8 пикселей) применение сжатия смысла не имеет, поскольку они и так малы. В случае более крупных изображений можно сэкономить довольно много места по сравнению с несжатыми форматами (например, *.BMP), используя сжатые форматы с потерями (например, *.JPG) или без потерь (например, *.PNG). Несжатые фоновые изображения с размерами порядка размеров экрана могут значительно увеличить общий размер приложения. Особое внимание следует уделять выбору форматов хранения для изображений, в которых один цвет будет считаться прозрачным во время выполнения; в таких случаях необходимо использовать только форматы со сжатием без потерь. Сжатие с потерями часто позволяет сэкономить много места, но этого удается достигнуть лишь ценой ослабления контроля за каждым отдельным пикселем изображения; вы получаете лишь приближенное изображение. Растровые изображения с областями прозрачности требуют точного указания цвета каждого пикселя.
Резюме
Создание отличного пользовательского интерфейса – это трудная, однако увлекательная задача проектирования. Во-первых, вы должны либо адаптировать идею своего проекта к привычным схемам использования и форм фактору выбранного вами целевого устройства, либо выбрать подходящий тип мобильных устройств, который соответствует проектным целям. Мобильные устройства значительно отличаются от настольных компьютеров и лэптопов своим интерфейсом и стереотипом использования. Также и различные классы устройств значительно отличаются друг от друга. Попытки разработки пользовательского интерфейса, способного хорошо работать на различных устройствах, – это гарантия того, что он будет плохо работать на каждом из них. Чтобы обеспечить наилучшие условия работы для пользователя, определяйте для себя целевые мобильные устройства и оптимизируйте интерфейс мобильного приложения применительно к каждому конкретному случаю.
В процессе принятия проектных решений очень важно учитывать, будут ли пользователи работать с интерфейсом вашего приложения с помощью одной или двух рук. Часто это решение диктуется особенностями оборудования, которое выбрано вами в качестве целевого; например, с сенсорными экранами обычно работают, используя две руки, а с мобильными телефонами – обычно одну. Явно укажите в своем основном документе проекта, для какого варианта использования предназначено приложение, и следите за учетом этого требования на протяжении всего процесса проектирования и разработки. При проектировании интерфейсов, которыми пользователь будет оперировать одной рукой, важно учитывать единообразие способов и простоту навигации в пределах интерфейса при помощи щелчков; не заставляйте пользователя при перемещении по часто встречающимся навигационным маршрутам менять кнопки. В процессе навигации по вашему приложению пользователь не должен быть вынужденным переводить взгляд с экрана устройства на клавиатуру; это отвлекает его и нарушает плавность течения его мыслей.
Огромное влияние на проект будут оказывать размеры экрана, являющегося целевым для вашего мобильного приложения. Для небольших экранов целесообразно использовать пользовательские интерфейсы, основанные на списках; в случае экранов большего размера, при работе с которыми применяются сенсорная площадка или мышь, лучшим решением для навигации между экранами будет метафора диалоговых окон-вкладок. Распределите функциональность своего мобильного приложения между несколькими специализированными экранами. Тщательно продумайте, какую информацию вы хотите отобразить на каждом из экранов и как облегчить навигацию между ними. Приложения для настольных компьютеров обычно отображают несколько абзацев информации одновременно. В приложениях для Pocket PC чаще встречается вариант отображения одного абзаца информации с одновременным отображением ссылок на другие абзацы. В смартфонах обычно отображаются сводные списки, с помощью которых пользователь может углубляться в структуру списков и просматривать каждую порцию информации по отдельности.
Поскольку мобильные устройства обычно не имеют полноценной клавиатуры, в большинстве случае быстрый ввод текста не является их сильной стороной. Поэтому, если требуется ввод данных, целесообразно не жалеть усилий на оптимизацию производительности труда пользователя при вводе распространенных разновидностей данных. Часто можно облегчить пользователю ввод таких специфических данных, как даты, числа, валюта, адреса или любые другие данные, отличающиеся от свободного текста, за счет разработки специализированных интерфейсов с крупными кнопками или адаптированных элементов управления. Обеспечить ускоренный ввод специфических данных могут также такие внешние устройства, как устройства для считывания штрих-кодов или устройства для распознавания речи и визуальных образов, однако ваше мобильное приложение должно предлагать пользователю и параллельные возможности ввода той же информации на случай сбоя упомянутых внешних устройств, что неизбежно случается.
Процесс разработки чрезвычайно ускоряется при использовании программных эмуляторов устройств, но эмуляторы не в состоянии заменить реальные устройства при тестировании удобства использования приложения. Эмулятора, выполняющегося на лэптопе, совершенно недостаточно для того, чтобы оценить истинные эксплуатационные характеристики приложения при его выполнении на физическом мобильном устройстве. Навигационные возможности, средства ввода, вес устройства, удобство работы и условия обзора данных – вот те параметры, точная оценка которых возможна только при тестировании приложения на реальном оборудовании.
В процессе написания кода пользовательского интерфейса для мобильного приложения очень важно структурировать код таким образом, чтобы внесение изменений в ранее разработанные участки кода, если это потребуется, не составляло труда. Получение окончательного варианта пользовательского интерфейса будет сопровождаться постоянным возвратом к пересмотру ранее принятых вами схем компоновки и навигации. Чтобы эти изменения можно было легко вносить, ваш код должен быть гибким. Для изоляции обработки событий одних элементов управления от обновления других могут эффективно использоваться централизация управления кодом пользовательского интерфейса в конечном автомате и интерфейсные функции, что позволит существенно повысить гибкость вашего проекта. Крайне важно избегать распределения ответственности за управление пользовательским интерфейсом между различными частями приложения; чем больше степень централизации кода, управляющего пользовательским интерфейсом, тем проще его будет модифицировать, если в этом возникнет необходимость. Использование вспомогательных классов для группирования родственных функций пользовательского интерфейса, например, всех обработчиков событий элементов управления, расположенных на данной вкладке, также способствует изоляции кода пользовательского интерфейса от остального кода. Надежно абстрагированный интерфейс между функциональной логикой приложения и логикой уровня представления крайне важен для повышения гибкости проекта. Дополнительным преимуществом создания надежно инкапсулированного кода пользовательского интерфейса является то, что это значительно облегчает перенос вашего мобильного приложения на мобильные устройства других классов.
.NET Compact Framework предлагает некоторые улучшенные возможности пользовательского интерфейса, которые могут пригодиться вам при разработке интерфейсов для многофункциональных мобильных приложений. .NET Compact Framework предоставляет разработчикам возможность создавать пользовательские элементы управления двух видов: 1) пользовательские элементы управления, которые являются производными от класса System.Windows.Forms.Control и реализуют собственные возможности визуализации с нуля, и 2) пользовательские элементы управления, которые реализуют соответствующие свойства поверх существующих элементов управления путем произведения этих свойств от таких не являющихся абстрактными элементов управления, как System.Windows.Forms.Control.TextBox, и расширения свойств последних. Полезны обе разновидности пользовательских элементов управления. Чрезвычайно полезна возможность динамического создания пользовательских элементов управления во время выполнения; создание версии элемента управления .NET Compact Framework во время проектирования может оказаться трудоемкой задачей, и если только создание пользовательских элементов не является одним из сегментов вашей деятельности на рынке, то лучше отказаться от этого шага и просто создавать экземпляры пользовательских элементов управления динамически во время выполнения.
Возможность устанавливать прозрачные цвета при копировании растровых изображений позволяет приложению создавать богатые графические образы, которые могут вам пригодиться в приложениях развлекательного, производственного и научного характера.
Ключом к созданию рисунков с использованием прозрачности при работе с .NET Compact Framework является использование класса System.Drawing.Imaging.ImageAttributes; этот класс позволяет вашему коду устанавливать ключевой цвет, который будет трактоваться как прозрачный при копировании исходного растрового изображения в изображение назначения. Области прозрачности могут оказаться полезными при работе со всеми разновидностями растровых изображений, от текста и фигур, динамически рисуемых на битовых картах, до заранее подготовленных изображений, загружаемых во время выполнения. Используемые растровые изображения могут храниться в виде части двоичного образа вашего приложения; разворачивать приложение значительно легче, если количество файлов, от которых оно зависит, невелико.
Разработка пользовательского интерфейса для мобильного устройства – это трудная, но благодарная работа, которая может доставить массу удовольствия. Она требует проявления незаурядного творчества и понимания того, какая существенная информация должна быть представлена пользователю, и какая метафора средств навигации будет наиболее подходящей. Также чрезвычайно интересно проводить различного рода эксперименты, что позволит вам очень быстро учиться по мере того, как вы будете на практике испытывать самые различные концепции. Как уже отмечалось в предыдущих разделах данной книги, то, насколько производительным приложение кажется пользователю, является очень важным аспектом приложения, которое можно считать удобным в работе. Если вы настроены на поддержание высокой производительности приложения, творчески мыслите и пишете код, предусматривая в нем встроенные средства обеспечения гибкости, то работа и эксперименты в процессе проектирования пользовательских интерфейсов приложений для мобильных устройств значительно расширят ваш опыт и доставят огромное удовольствие.







