Глава 3 Элементы управления

Сходство и различия

Несмотря на свою схожесть, .NET Compact Framework уступает в функциональности базовой библиотеке .NET Framework. Это относится и к элементам управления. К счастью, кнопки, списки и текстовые поля все же присутствуют в мобильной версии. Кроме того, в .NET Compact Framework 2.0 была добавлена поддержка еще нескольких элементов управления, которые отсутствовали в NET Compact Framework 1.0.

Рис. 3.1. Свойства, поддерживаемые в .NET Compact Framework

Нужно помнить, что даже поддерживаемые элементы управления имеют порой ограниченные возможности. Чтобы узнать, какие свойства, методы или события не поддерживаются элементом управления, нужно запустить справочную систему, найти нужный класс и просмотреть все члены класса. Если нужное свойство поддерживается в .NET Compact Framework, то у его описания будет присутствовать значок мобильного устройства (рис. 3.1). В качестве примера можно открыть страницу с описанием класса

Registry
. Легко заметить, что поля
CurrentUser
,
LocalMachine
и
Users
поддерживаются в .NET Compact Framework, а поля
DynData
и
PerfomanceData
— нет.

Но даже если необходимый объект поддерживается в .NET Compact Framework, то все равно следует внимательно ознакомиться с его описанием. Например, поле

LocalMachine
поддерживается только в NET Compact Framework 2.0, поэтому при разработке нужно решить, стоит ли использовать это поле (рис. 3.2).

Рис. 3.2. Просмотр поддержки версий .NET Compact Framework

В следующем списке перечислены элементы управления, которые не входят в состав классов библиотеки .NET Compact Framework 1.0:

CheckedListBox
;

ColorDialog
;

ErrorProvider
;

FontDialog
;

GroupBox
;

HelpProvider
;

LinkLabel
(поддерживается в .NET Compact Framework 2.0);

NotificationBubble
;

NotifyIcon
;

□ элементы управления, связанные с печатью;

RichTextBox
;

Splitter
(поддерживается в .NET Compact Framework 2.0).

В Compact .NET Framework 2.0 были добавлены новые элементы управления, которые перечислены в следующем списке.

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

DateTimePicker
— элемент для выбора даты и времени. Он достаточно компактен, что позволяет широко использовать его в приложениях.

WebBrowser
— элемент, который реализует функциональность браузера.

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

DocumentList
— элемент управления, обеспечивающий стандартный механизм для управления файлами. Пример работы данного элемента можно увидеть при открытии файлов в приложениях Excel Mobile и Word Mobile. Элемент
DocumentList
позволяет перемещаться по файловой системе и выполнять стандартные файловые операции.

DataGrid
— элемент для отображения данных в табличном виде. Теперь может использоваться и в приложениях для смартфонов.

LinkLabel
— элемент управления для создания гипертекстовых ссылок.

Splitter
— элемент управления, позволяющий изменять размеры других элементов.

HardwareButton
— элемент управления, позволяющий управлять кнопками карманного компьютера.

Урезанная функциональность элементов управления

Кроме отсутствия некоторых элементов управления, в .NET Compact Framework также была урезана функциональность имеющихся элементов. Наиболее часто употребляемые элементы управления с урезанной функциональностью приведены в следующем списке:

AcceptButton
;

CancelButton
;

AutoScroll
(поддерживается в .NET Compact Framework 2.0);

Anchor
(поддерживается в .NET Compact Framework 2.0);

□ элементы Multiple Document Interface (MDI);

KeyPreview
(поддерживается в .NET Compact Framework 2.0);

TabIndex
(поддерживается в .NET Compact Framework 2.0);

TabStop
(поддерживается в .NET Compact Framework 2.0).

Также наложены ограничения на технологию drag and drop и на поддержку графики. Во многих классах поддерживаются не все свойства, события и методы.

Однако в .NET Compact Framework 2.0 ограничений стало меньше. Например, элементы управления теперь обладают свойствами

TabIndex
и
TabStop
.

Элемент Form

Элемент

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

Свойство FormBorderStyle

Свойство

FormBorderStyle
определяет стиль формы. По умолчанию используется стиль
FormBorderStyle.FixedSingle
. При этом форма заполняет все рабочее место экрана, и пользователь не может изменять размеры формы или перемещать ее по экрану. При установке значения
FormBorderStyle.None
создается форма без рамки и заголовка. В этом случае можно изменять размеры и расположение формы программно, но пользователь по-прежнему не может манипулировать формой.

Свойство ControlBox

Свойство

ControlBox
отвечает за отображение контейнера для элемента управления. Если свойство
ControlBox
имеет значение
True
, то контейнер будет отображаться. В противном случае он на экран не выводится. Для устройств Pocket PC подобный контейнер может содержать только одну кнопку.

Свойства MinimizeBox и MaximizeBox

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

MinimizeBox
. Если оно имеет значение
True
, то кнопка при нажатии будет сворачивать форму. Значение
False
позволяет создавать кнопку закрытия формы. Значение свойства
MaximizeBox
игнорируется системой.

Свойство WindowsState

Свойство

WindowsState
определяет состояние окна при первоначальной загрузке. Разработчик может использовать значения
FormWindowState.Normal
и
FormWindowState.Maximized
. Если свойство имеет значение
FormWindowState.Normal
, то форма заполняет весь экран, за исключением нижней полоски меню и верхней полоски системного меню
Start
(Пуск). При использовании значения
FormWindowState.Maximized
форма заполняет экран полностью, скрывая системное меню
Start
(Пуск), но при этом нижняя полоса меню остается видимой.

Размеры и расположение формы

Свойство

Size
позволяет задавать размеры формы. Это свойство игнорируется, если свойство
FormBorderStyle
имеет значение
FixedSingleProperty
.

Свойство

Location
задает координаты верхнего левого угла формы. Но так как форма обычно заполняет весь экран, то в большинстве случаев это свойство не используется.

Элементы управления

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

Элемент Button

Для создания обычной кнопки используется класс

System.Windows.Forms.Button
. Эта кнопка обладает всеми основными функциями, которые есть у такого же класса в полной версии .NET Framework. Кнопка предназначена для обработки нажатия стилуса на соответствующую область экрана. В этом случае возникает событие
Click
. Код, приведенный в листинге 3.1, является обработчиком этого события. Он выводит текущее время в текстовое поле после нажатия на кнопку с надписью
Узнать время
.

Листинг 3.1

private void butGetTime_Click(object sender, EventArgs e) {

 txtCurTime.Text = DateTime.Now.ToLongTimeString();

}

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

Рис. 3.3. Результат нажатия на кнопку

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

Функциональность элемента управления

Button
очень сильно урезана по сравнению с полной версией .NET Framework. В частности, у данного элемента нет свойств
Image
и
ImageList
, которые применяются для отображения на кнопке графики.

Элемент TextBox

В предыдущем примере дата отображалась в текстовом поле. Это поле создается при помощи класса

TextBox
, который позволяет вводить текст. Данный элемент поддерживает такие стандартные свойства, как
BackColor
и
ForeColor
. Событие
Click
элементом
TextBox
не поддерживается, но разработчик может воспользоваться событиями
KeyPress
,
KeyUp
и
KeyDown
. Следует отметить особенность этого элемента. Несмотря на то что класс
TextBox
поддерживает свойство
PasswordChar
, при вводе пароля на экране всегда будет использоваться символ звездочки. Задать другой символ не получится.

Также текстовое поле не поддерживает свойство

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

Листинг 3.2

private void txtCurTime_KeyPress(object sender, KeyPressEventArgs e) {

 if (Char.IsLetter(e.KeyChar)) {

  // сохраняем текущую позицию каретки

  int pos = txtCurTime.SelectionStart;

  // переводим в верхний регистр

  txtCurTime.Text =

   txtCurTime.Text.Insert(txtCurTime.SelectionStart,

   Char.ToUpper(e.KeyChar).ToString());

  // перемещаем каретку в новую позицию

  txtCurTime.SelectionStart = pos + 1;

  e.Handled = true;

 }

}

ПРИМЕЧАНИЕ

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

Элемент Label

В рассмотренном примере также использовался элемент

Label
для отображения текстовой строки. Как правило, надпись используется для отображения некоторого текста, который пользователь не может изменить. Сама отображаемая строка задается при помощи свойства
Text
. Текст на экране можно выравнивать с помощью свойства
TextAlign
. Разработчик может использовать значения
TopLeft
,
TopCenter
и
TopRight
. При изменении текста в метке инициируется событие
TextChanged
. При создании элемента нужно следить за длиной отображаемой строки. Если текст слишком большой и не помещается в пределах элемента, то он попросту обрезается.

В отличие от полной версии .NET Framework, элемент Label в .NET Compact Framework не поддерживает такие свойства, как

AutoSize
,
BorderStyle
,
Image
,
ImageList
и многие другие. Также не поддерживается событие
Click
. Впрочем, на практике редко возникает нужда в обработке этого события.

Элемент RadioButton

Элемент управления

RadioButton
позволяет создавать переключатели, объединенные в группы. Вся группа переключателей должна располагаться в контейнере. Примером такого контейнера может служить сама форма, но чаще используется элемент
Panel
.

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

RadioButton
. В любом случае группы переключателей не зависят друг от друга.

При изменении состояния переключателя в классе

RadioButton
инициируются события
Click
и
CheckedChanged
. Событие
Click
возникает, когда пользователь щелкает стилусом на самом переключателе. Событие
CheckedChanged
возникает, когда состояние элемента
RadioButton
меняется программно или в результате действий пользователя. Событие
Click
не инициируется, когда свойство
CheckedChanged
меняется программно.

Для демонстрации примера работы с элементом

RadioButton
можно создать аналог популярной телеигры «Кто хочет стать миллионером?». На экране будет отображаться вопрос, а пользователь должен выбрать из представленных вариантов единственный правильный ответ. Код, реализующий основную функциональность приложения, приведен в листинге 3.3.

Листинг 3.3

private void radClub1_CheckedChanged(object sender, EventArgs e) {

 if (this.radClub1.Checked)

  MessageBox.Show("Увы, вы проиграли", "Ошибка!");

}


private void radClub2_CheckedChanged(object sender, EventArgs e) {

 if (this.radClub2.Checked)

  MessageBox.Show("Поздравляю! Вы выиграли миллион!", "Миллион!");

}


private void radClub3_CheckedChanged(object sender. EventArgs e) {

 if (this.radClub3.Checked)

  MessageBox.Show("Увы, вы проиграли", "Ошибка!");

}


private void radClub4_CheckedChanged(object sender. EventArgs e) {

 if (this.radClub4.Checked)

  MessageBox.Show ("Увы, вы проиграли", "Ошибка!");

}

На рис. 3.4 показан внешний вид этого приложения.

Рис. 3.4. Демонстрация работы независимых переключателей

В полной версии .NET Framework в качестве контейнера для переключателей часто используется элемент

GroupBox
, который на данный момент не поддерживается в библиотеке .NET Compact Framework. Также не поддерживаются некоторые свойства, к которым относятся
Appearance
,
Image
и
ImageList
.

Элемент Panel

Элемент управления Panel используется в качестве контейнера для размещения других элементов управления. Так как .NET Compact Framework не поддерживает элемент управления

GroupBox
, то для группировки таких элементов, как переключатели
RadioButton
, приходится использовать именно
Panel
.

В версии .NET Compact Framework элемент не поддерживает свойства

BorderStyle
,
BackGroundImage
и
AutoScroll
.

Элемент CheckBox

Элемент управления

CheckBox
позволяет создавать независимый переключатель в виде флажка. Элемент
CheckBox
имеет свойство
CheckState
, позволяющее определить состояние переключателя. Программист может использоваться значения
Unchecked
,
Checked
и
Indeterminate
. Значение
Unchecked
свидетельствует о том, что флажок в переключателе не взведен. Если переключатель все же включен, то используется значение
Checked
. Но значение
Indeterminate
требует некоторых пояснений. Состояние
Indeterminate
используется, когда для свойства
ThreeState
элемента
CheckBox
установлено значение
True
. Если свойство
CheckState
имеет значение
Indeterminate
, то элемент окрашен серым цветом, но, тем не менее, считается помеченным. При этом пользователь не может изменить состояние переключателя.

Также элемент не распознает событие

Click
, если свойство
AutoCheck
имеет значение
False
. Для этого свойства нужно задать значение
True
, чтобы пользователь мог пользоваться стилусом для работы с переключателем.

Также элемент также не поддерживает некоторые свойства, в частности,

ImageIndex
.

Элемент ComboBox

Элемент управления

ComboBox
позволяет создавать поле со списком выбора. Благодаря своей компактности этот элемент управления хорошо подходит для тех задач, когда требуется экономить место на экране. Поле со списком выглядит как обычное текстовое поле
TextBox
со стрелкой, которая расположена в правой части поля. Когда пользователь щелкает по стрелке, то открывается список с предварительно заданными элементами. Когда пользователь выбирает определенный пункт списка или снова щелкает по стрелке, то список снова сворачивается.

Добавлять текстовые элементы в

ComboBox
можно как в режиме проектирования, так и программно во время работы программы.

В листинге 3.4 приведен пример добавления пунктов программным путем. Для этого нужно вызвать метод

Add
в свойстве коллекции
Items
элемента
ComboBox
. Отдельные пункты можно удалять с помощью метода
Remove
, а чтобы удалить все пункты сразу, применяется метод
Clear
. Приведенный пример показывает, как можно добавить три строки в элемент
ComboBox
с именем
comboBox1
.

Листинг 3.4

comboBox1.Items.Add("Мурзик");

comboBox1.Items.Add("Барсик");

comboBox1.Items.Add("Рыжик");

Чтобы узнать, какой элемент выбрал пользователь, применяется свойство

SelectedIndex
или
SelectedItem
. Свойство
SelectedIndex
возвращает порядковый номер выбранного пункта. Этот номер можно использовать для доступа к выбранному пункту при помощи свойства
Items
. Следует помнить, что нумерация элементов начинается с нуля. Пример работы со свойством
SelectedIndex
приведен в листинге 3.5. Также в этом листинге показано, как можно получить доступ к выбранному пункту при помощи свойства
SelectedItem
.

Листинг 3.5

// Получим выделенный пункт с помощью SelectedIndex

string selItem = (string)cmbCats.Items[cmbCats.SelectedIndex];

MessageBox.Show(selItem);

// Второй способ - получим пункт с помощью

SelectedItem string selItem = cmbCats.SelectedItem.ToString();

MessageBox.Show(selItem);

В полной версии .NET Framework у элемента

ComboBox
для свойства
DropDownStyle
можно задавать значения
Simple
,
DropDownList
или
DropDown
. В .NET Compact
Framework
значение
Simple
не используется. До выхода .NET Compact Framework 2.0 также не поддерживалось и значение
DropDown
. Кроме того, по умолчанию в .NET Compact Framework применяется значение
DropDownList
, тогда как в полной версии .NET Framework по умолчанию используется стиль
DropDown
. Также не поддерживаются многие методы из основной версии библиотеки. В .NET Compact Framework 2.0 у поля со списком появилась поддержка методов
BeginUpdate
и
EndUpdate
, которые позволяют избежать мерцания при загрузке большого числа элементов.

ВНИМАНИЕ

Внешний вид и поведение элемента ComboBox в смартфонах немного отличается от аналогичных элементов в КПК. Более подробно об отличиях будет рассказано в соответствующей главе.

Элемент ListBox

Элемент

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

Элементы

ComboBox
и
ListBox
имеют почти одинаковый набор свойств и методов. В листинге 3.6 показано, как можно программно добавить несколько строк в список
ListBox
.

Листинг 3.6

lstFruit.Items.Add("Яблоко");

lstFruit.Items.Add("Груша");

lstFruit.Items.Add("Слива");

lstFruit.Items.Add("Персик");

Свойство

SelectedIndex
содержит порядковый номер выбранного элемента списка. Если указать этот индекс в коде приложения, то выбранный элемент будет немедленно выделен в списке соответствующим цветом. Если никакой элемент не выбран, то свойство
SelectedIndex
имеет значение -1. Также класс поддерживает свойство
SelectedItem
, которое соответствует одноименному свойству класса
ComboBox
.

Из часто используемых свойств элемента

ListBox
в полной версии NET Framework можно выделить свойство
MultiColumn
, которое не поддерживается в .NET Compact Framework. В нем отсутствует горизонтальная полоска прокрутки, даже если строки текста не умещаются в списке полностью. Также не поддерживается многострочное выделение, поэтому пользователь может выбрать только один элемент списка.

Элемент NumericUpDown

Элемент

NumericUpDown
позволяет создавать счетчик с числовым полем ввода. Такой элемент интерфейса помогает пользователю быстро выбрать число из заданного диапазона. Элемент может работать только с целыми числа типа
Integer
. Десятичные значения округляются.

Разработчик управляет поведением элемента

NumericUpDown
при помощи свойств
Minimum
,
Maximum
,
Value
и
Increment
. Свойства
Minimum
и
Maximum
определяют максимальное и минимальное значения элемента. Свойство
Value
содержит текущее значение в поле ввода. Свойство
Increment
определяет величину увеличения или уменьшения значения в поле, когда пользователь нажимает кнопки со стрелками. Текущее значение всегда увеличивается и уменьшается на значение свойства
Increment
, даже если результат выходит за диапазон, определенный свойствами
Minimum
и
Maximum
.

Пользователь также может изменить свойство

Value
, просто указав соответствующее значение в поле. Если это значение находится в интервале между
Minimum
и
Maximum
, тогда свойства
Value
и
Text
изменятся в соответствии с введенным значением. Если новое значение выходит за рамки заданных значений, то свойство
Text
отображает введенное число, а свойство
Value
принимает значение, которое приписано свойству
Maximum
. Чтобы запретить пользователю указывать числа в поле ввода, нужно для свойства
ReadOnly
задать значение
True
.

При изменении значения элемента

NumericUpDown
инициируется событие
ValueChanged
. Оно возникает только в том случае, если значение меняется программно или когда пользователь нажал кнопки со стрелками. При вводе числа событие не инициируется. В листинге 3.7 продемонстрирован пример использования элемента
NumericUpDown
и обработки события
ValueChanged
.

Листинг 3.7

private void numericUpDown1_ValueChanged(object sender, EventArgs e) {

 int year = (int)this.numericUpDown1.Value;

 this.lblNote.Text = "Вы выбрали " + year.ToString() + "год";

}

На рис. 3.5 показано, как функционирует элемент

NumericUpDown
.

Рис. 3.5. Выбор года при помощи элемента NumericUpDown

При работе с элементом

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

Стоит проиллюстрировать эту ситуацию. Итак, у нас установлено текущее значение, равное 1992. Значение свойства

Increment
равно 6, а максимум ограничен значением 2006. Последовательные нажатия стрелки вверх доведут значение с 1992 до 2006. Итак, максимальное значение достигнуто. Теперь надо нажать кнопку со стрелкой, направленной вниз. Казалось бы, на экране должно быть показано число 2000 (2006-6), но следует учитывать, что перед превышением максимального значения счетчик запомнил число 2004. Именно от него будет отсчитываться разница, и на экране будет отображено число 1998.

Элемент DomainUpDown

Элемент

DomainUpDown
позволяет создавать счетчик с текстовым полем ввода. Этот элемент похож на элемент
NumericUpDown
, а его функциональность схожа с теми возможностями, которые предоставляют
ComboBox
или
ListBox
. Но в элементе
DomainUpDown
вместо чисел используются строки. Этот элемент очень широко применяется для построения интерфейса, так как он весьма компактен и не занимает много места на маленьком экране карманного компьютера. Следует учитывать, что пользователь не может увидеть весь список. Если свойство
ReadOnly
имеет значение
True
, то пользователь может выбирать только заранее заданные строки из списка. Если это свойство имеет значение
False
, то пользователь сможет добавить свой текст в поле ввода. Впрочем, напечатанный текст все равно не войдет в список.

Так же как и элемент

NumericUpDown
, данный элемент управления содержит текстовое поле и две кнопки со стрелками с правой стороны. Пользователь может использовать эти стрелки для прокрутки списка строк или ввести в поле свой текст, если свойство
ReadOnly
имеет значение
False
.

При создании объекта свойство

SelectedIndex
имеет значение -1, показывающее, что ни один элемент списка пока еще не выбран. Если нужно выделить тот или иной пункт списка при загрузке элемента, то в свойстве
SelectedIndex
нужно указать соответствующий порядковый номер. В листинге 3.8 приведен пример, иллюстрирующий программное добавление строк в список и методику обработки события
SelectedItemChanged
.

Листинг 3.8

private void Form1_Load(object sender, System.EventArgs e) {

 domainUpDown1.Items.Add("Item 1");

 domainUpDown1.Items.Add("Item 2");

 domainUpDown1.Items.Add("Item 3");

 domainUpDown1.Items.Add("Item 4");

 domainUpDown1.ReadOnly = true;

}


private void domainUpDown1_SelectedItemChanged(object sender,

 System.EventArgs e) {

 label1.Text = domainUpDown1.SelectedIndex.ToString();

 label2.Text = domainUpDown1.Items[domainUpDown1.SelectedIndex].ToString();

}

Элемент ProgressBar

Элемент управления

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

Чаще всего разработчик оперирует свойствами

Minimum
,
Maximum
и
Value
. Свойства
Minimum
и
Maximum
задают минимальное и максимальное значения свойства
Value
. А свойство
Value
определяет текущее значение индикатора.

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

Hide
или свойства
Visible
.

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

Листинг 3.9

private void tmrCook_Tick(object sender, EventArgs e) {

 if (this.progressBar1.Value < this.progressBar1.Maximum) {

  this.progressBar1.Value += 1;

  lblCounter.Text = this.progressBar1.Value.ToString();

 }

 if (this.progressBar1.Value >= this.progressBar1.Maximum) {

  tmrCook.Enabled = false;

  MessageBox.Show("Яйца сварились!");

  this.progressBar1.Value = 0;

  lblCounter.Text = "0";

 }

}


private void butStart_Click(object sender, EventArgs e) {

 tmrCook.Enabled = true;

}

На рис. 3.6 показан внешний вид приложения в момент отсчета времени.

Рис. 3.6. Индикатор прогресса, позволяющий сварить яйца вкрутую

Элемент StatusBar

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

StatusBar
. Чтобы изменить текст в элементе
StatusBar
, достаточно присвоить новое значение свойству
Text
. На рис. 3.7 показан внешний вид приложения в тот момент, когда пользователь нажимает на кнопку, а в листинге 3.10 приведен пример кода, который меняет текст в строке состояния.

Рис. 3.7. Пример работы со строкой состояния

Листинг 3.10

private void butClickMe_Click(object sender, EventArgs e) {

 this.statusBar1.Text = "Вы нажали на кнопку";

}

Строка состояния поддерживает только одну информационную панель, а также не распознает события

Click
.

Элемент TrackBar

Элемент управления

TrackBar
предназначен для установки числового значения при помощи перемещения ползунка по числовой шкале. Основную работу с элементом разработчик выполняет при помощи свойств
Minimum
,
Maximum
и
Value
. Ползунок может располагаться как вертикально, так и горизонтально. Ориентация ползунка задается при помощи свойства
Orientation
. Свойство
TickFrequency
регулирует дистанцию между метками шкалы. По умолчанию значение свойства
TickFrequency
равно единице.

Свойства

SmallChange
и
LargeChange
определяют шаг изменения значения
Value
. Свойство
SmallChange
задает изменения основного значения, когда пользователь нажимает на одну из кнопок навигации на самом карманном компьютере или на смартфоне.

Свойство

LargeChange
показывает, на сколько будет изменено основное значение, когда пользователь щелкнет стилусом на самом ползунке. При изменении значения свойства
Value
инициируется событие
ValueChanged
.

Для иллюстрации работы ползунка нужно создать новый проект и разместить на форме два элемента

TrackBar
. Один из них будет расположен горизонтально, а второй — вертикально. При этом положение ползунков на шкалах будет синхронизировано (рис. 3.8).

Рис. 3.8. Пример работы с ползунками

В листинге 3.11 приведен код, отвечающий за функциональность ползунков.

Листинг 3.11

private void trackVert_ValueChanged(object sender, EventArgs e) {

 this.trackHoriz.Value = this.trackVert.Value;

}


private void trackHoriz_ValueChanged(object sender, EventArgs e) {

 this.trackVert.Value = this.trackHoriz.Value;

}

Когда пользователь передвинет один ползунок, то второй ползунок автоматически будет переведен в то же положение, что и первый.

Элемент ToolBar

Элемент управления

ToolBar
позволяет создавать собственную панель инструментов. Во многих случаях использование панели инструментов может принести разработчику больше выгод, чем применение меню. Следует учитывать, что панель инструментов позволяет использовать изображения, что делает работу с этим элементом удобным и наглядным. В .NET Compact Framework элемент
ToolBar
не может содержать текст. Все инструменты маркируются только при помощи графических изображений. Изображения связываются с элементом при помощи класса
ImageList
. В приложениях для КПК панель инструментов всегда располагается в нижней части экрана справа от пунктов меню (рис. 3.9).

Рис. 3.9. Панель инструментов в приложении

Чтобы добавить в приложение элемент

ToolBar
, нужно сначала переместить на форму элемент управления
ImageList
. Значок
ImageList
появится в нижней части окна
Form Designer
рядом с элементом
mainMenu
. В окне редактора свойств
Properties
нужно выбрать свойство
Images
и нажать кнопку редактирования. В результате будет открыто диалоговое окно
Image Collection Editor
.

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

Теперь на форму надо перенести элемент

ToolBar
. В его свойстве
ImageList
надо указать имя добавленного ранее элемента
ImageList
. В рассматриваемом примере использовалось имя по умолчанию
ImageList1
. Затем надо перейти к свойству
Buttons
и активировать окно редактора
ToolBarButton Collection Editor
. Так как было добавлено три изображения для кнопок, то нужно три раза нажать кнопку
Add
. Для каждой добавленной кнопки следует задать свойство
ImageIndex
. При необходимости разработчик может изменить стиль отображения кнопок. По умолчанию используется стиль
PushButton
, который создает обычные кнопки. Если для кнопки задать стиль
DropDownButton
, то при ее нажатии будет отображаться меню или другое окно. Справа от кнопки на панели инструментов отображается стрелка.

Стиль

Separator
позволяет создавать разделители между кнопками на панели управления. Стиль
ToggleButton
позволяет создавать переключаемую кнопку. При первом нажатии она переходит в активированное состояние, в котором и остается до тех пор, пока кнопку не нажмут повторно.

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

ToolBar
возникает событие
ButtonClick
. В листинге 3.12 приведен код, обрабатывающий нажатие первых двух кнопок.

Листинг 3.12

private void toolBar1_ButtonClick(object sender,

 ToolBarButtonClickEventArgs e) {

 if (e.Button == this.toolBarButton1) {

  MessageBox.Show("Вы выбрали первую кнопку");

 } else if (e.Button == this.toolBarButton2) {

  MessageBox.Show("Вы выбрали вторую кнопку");

 }

}

Элемент MainMenu

Меню является одним из самых важных элементов графического интерфейса Windows-приложений. Не являются исключением и программы для мобильных устройств. По умолчанию на форме уже присутствует элемент

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

Следует помнить, что в приложениях для Pocket PC меню располагается в нижней части окна программы, тогда как в приложениях для обычных компьютеров меню располагается в верхней части окна. Если в программе одновременно присутствуют меню и панель инструментов, то они будут отображаться вместе. Но меню будет прижато к левой границе окна, а панель инструментов — к правой. Пример работы с меню приведен в листинге 3.13.

Листинг 3.13

private void mnuAboutClick(object sender, EventArgs e) {

 MessageBox.Show("Это моя программа!");

}


private void mnuExitClick(object sender, EventArgs e) {

 this.Close();

}

Элемент ContextMenu

Элемент

ContextMenu
позволяет создавать контекстные меню для других элементов интерфейса. Этот элемент очень похож на элемент управления
MainMenu
. Но если
MainMenu
всегда связан с формой приложения, то
ContextMenu
можно связать с любым элементом формы. Так как в КПК не используется мышь, то вызов контекстного меню вызывается операцией tap-and-hold вместо привычного щелчка правой клавишей мыши.

ВНИМАНИЕ

Если вы пользуетесь эмулятором, то для имитации tap-and-hold нужно щелкнуть левой кнопки мыши и не отпускать ее некоторое время.

Чтобы добавить элемент

ContextMenu
в приложение, нужно сначала переместить его значок на форму. Он появится в нижней части редактора
Form Designer
, там же, где и элемент
MainMenu
. Но на самом деле во время выполнения программы контекстное меню будет отображаться рядом с выбранным элементом интерфейса. Также контекстное меню можно создавать программно во время запуска приложения.

При вызове контекстного меню инициируется событие

Popup
. Когда пользователь выбирает какой-то пункт меню, то возникает событие
Click
. Чтобы привязать созданное контекстное меню к конкретному элементу интерфейса, нужно выбрать его на форме и в свойстве
ContextMenu
указать созданное контекстное меню.

ПРИМЕЧАНИЕ

До выхода .NET Compact Framework 2.0 элемент управления ContextMenu не поддерживал свойство ContextMenu.SourceControl

Элемент Timer

Элемент

Timer
позволяет выполнять некоторые действия по истечении заданных интервалов времени. Чаще всего для работы с таймером разработчик применяет событие
Tick
. Данное событие инициируется только в том случае, если свойство
Enabled
имеет значение
True
. Если нужно остановить таймер, то достаточно присвоить данному свойству значение
False
.

Интервал отсчета времени задается свойством

Interval
, а его значение указывает используемый промежуток времени в миллисекундах. Если рабочий интервал таймера должен составлять 3 с, то надо установить значение 3000.

Этот элемент управления уже применялся при работе с объектом

ProgressBar
.

Элементы OpenFileDialog и SaveFileDialog

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

OpenFileDialog
и
SaveFileDialog
. К сожалению, в версии .NET Compact Framework возможности данных элементов управления серьезно урезаны. Разработчик может манипулировать файлами только в пределах папки
My Documents
и вложенных папок следующего уровня. Поэтому папка
My Documents\Programming\Sample
будет уже недоступна.

Рассматриваемые элементы управления размещаются в нижней части дизайнера формы рядом с элементом

MainMenu
. При работе с данными элементами прежде всего надо позаботиться о свойстве
Filter
, которое ограничивает список доступных файлов, фильтруя их по расширению. Свойство
InitalDirectory
содержит имя папки, в которой по умолчанию располагаются файлы. Если это свойство оставить пустым, то обзор файлов начнется с самой папки
My Documents
.

Основным методом для этих элементов является

ShowDialog
. После его вызова на экране отображается модальное окно, в котором пользователь должен нажать кнопку
OK
или
Cancel
. При этом метод
ShowDialog
возвращает значения
DialogResult.OK
и
DialogResult.Cancel
соответственно. Если получено значение
DialogResult.OK
, то пользователь нажал кнопку
OK
и в свойстве
Filename
содержится полный путь к выбранному файлу.

Пример работы с элементами

OpenFileDialog
и
SaveFileDialog
приведен в листинге 3.14.

Листинг 3.14

private void butOpen_Click(object sender, EventArgs e) {

 ofd.Filter = "DLL|*.dll|Картинки|*.jpg";

 ofd.InitialDirectory = "\\My Documents\\Templates";

 if (DialogResult.OK == ofd.ShowDialog()) {

  statusBar1.Text = ofd.FileName;

 } else {

  statusBar1.Text = "Вы нажали на кнопку Отмена!";

 }

}

Элементы HScrollBar и VScrollBar

Элементы управления

HScrollBar
и
VScrollBar
позволяют создавать полосы прокрутки для элементов, которые изначально не обладают этой функциональностью. Пользоваться этими полосами прокрутки совсем не сложно. Свойство
Minimum
задает значение элемента, когда ползунок находится в крайней левой или в крайней верхней позиции, для
HScrollBar
или
VScrollBar
соответственно. Свойство
Maximum
, задает максимальное значение для полос прокрутки. Значение свойства
Value
зависит от положения ползунка. Оно всегда находится в диапазоне между значениями свойств
Minimum
и
Maximum
.

Когда пользователь щелкает на полосе прокрутки, то свойство Value изменяется в соответствии со значением, заданным в свойстве

LargeChange
. Когда пользователь нажимает на кнопку навигации со стрелкой, то свойство Value изменяется в соответствии со значением, заданным в свойстве
SmallChange
. Следует обратить внимание на то, что если ползунок находится в положении, определяемом свойством
Maximum
, то свойство
Value
не равно значению
Maximum
. В этом случае значение свойства
Value
вычисляется по формуле
Maximum - LargeChange + 1
.

При изменении свойства

Value
инициируется событие
ValueChanged
. В листинге 3.15 приведен пример работы с полосами прокрутки.

Листинг 3.15

private void vScrollBar1_ValueChanged(object sender, EventArgs e) {

 this.lblScroll.Text = this.vScrollBar1.Value.ToString();

}

На рис. 3.10 показан внешний вид приложения. Если переместить ползунок в нижнюю часть полосы прокрутки, то значение в соответствии с формулой будет равно 91.

Рис. 3.10. Пример работы с полосами прокрутки


Список рисунков (ImageList)

Элемент управления

ImageList
уже рассматривался при знакомстве с элементом
ToolBar
. Элемент
ImageList
используется для хранения коллекций растровых изображений. Как и многие другие элементы, список рисунков не отображается во время выполнения программы, а используется как контейнер, из которого по мере необходимости извлекаются хранимые изображения. Как правило, данный элемент используется совместно с такими элементами управления, как
ListView
,
TreeView
и
ToolBar
.

Изображения можно добавлять в элемент управления во время работы приложения. Для этого используется метод

Add
, который входит в состав члена класса
Images
. Сами картинки могут располагаться как в отдельных файлах, так и в ресурсах приложения. В листинге 3.16 показано, как можно добавить картинку из ресурсов в
ImageList
, а затем отобразить ее в элементе интерфейса
PictureBox
.

Листинг 3.16

Bitmap image = new Bitmap(Assembly.GetExecutingAssembly(),

 GetManifestResourceStream(@"ImageList_CS.home.gif"));

imgList.Images.Add(image);

picTest.Image = imgList.Images[0];

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

ImageList
уже было одно изображение, то новая картинка будет иметь порядковый номер, равный единице. Это иллюстрируется листингом 3.17.

Листинг 3.17

private void butFromImageListClick(object sender, EventArgs e) {

 picTest.Image = imgList.Images[1];

}

Все картинки, находящиеся в

ImageList
, имеют одинаковый размер. По умолчанию используется размер 16×16 пикселов. Разработчик может изменить размеры изображений, используя свойство
ImageSize
. Если менять отображаемые картинки при помощи таймера, то можно даже создать небольшую мультипликацию. Для этого достаточно список рисунков заполнить набором изображений, а затем поочередно отображать их в графическом поле.

Элемент PictureBox

Элемент управления

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

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

Листинг 3.18

private void butFromFile_Click(object sender, EventArgs e) {

 picTest.Image = new Bitmap(@"\Windows\banner.gif");

}

Если использовать этот способ для добавления картинки, то нужно добавить изображение в проект и для свойства

Build Action
в окне свойств
Properties
задать значение
Content
. В процессе подготовки приложения к инсталляции изображение будет рассматриваться как часть программы. В рассмотренном примере использовалась готовая картинка, которая находится в папке
Windows
.

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

Build Action
задать значение
Embedded Resource
. Тогда не придется специально включать изображения в состав инсталлятора. В листинге 3.19 приведен пример, иллюстрирующий добавление изображения из ресурсов.

Листинг 3.19

private void butRes_Click(object sender, EventArgs e) {

 // Загружаем из ресурсов

 picTest.Image = new Bitmap(Assembly.GetExecutingAssembly().

  GetManifestResourceStream("PictureBox_CS.kristina.jpg"));

}

Элемент

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

Листинг 3.20

private void butImgList_Click(object sender, EventArgs e) {

 // изменяем размеры картинки

 imageList1.ImageSize = new System.Drawing.Size(160, 120);

 // загружаем картинку с измененными размерами

 picTest.Image = imageList1.Images[0];

}

На рис. 3.11 показан внешний вид приложения, в котором для работы с изображениями применяются все три описанных варианта.

Рис. 3.11. Пример работы с элементом PictureBox

Элемент ListView

Элемент управления

ListView
похож на элемент
ListBox
, но вместо обычного текста данный элемент может показывать изображения. Фактически, правая часть рабочего окна Проводника в Windows XP является типичным примером использования этого органа управления. Элементы в
ListView
могут отображаться в виде таблицы, списка, а также как группа крупных и мелких значков. За способ отображения содержимого отвечает свойство
View
. Значение
Details
позволяет отображать содержимое в виде таблицы, значение
List
создает список, значение
LargeIcon
позволяет отображать элементы списка в виде больших пиктограмм, а значение
SmallIcon
отображает их как маленькие пиктограммы.

В режиме

Details
элемент управления
ListView
позволяет создавать дополнительные столбцы. Их можно добавлять как во время проектирования, так и во время исполнения программы. Пример добавления столбцов во время работы приложения приведен в листинге 3.21.

Листинг 3.21

private void Form1_Load(object sender, EventArgs e) {

 // Устанавливаем нужный вид

 listView1.View = View.Details;

 // Выделяем всю строку при выделении любого элемента

 listView1.FullRowSelect = true;


 ColumnHeader columnHeader1 = new ColumnHeader();

 ColumnHeader columnHeader2 = new ColumnHeader();

 ColumnHeader columnHeader3 = new ColumnHeader();


 columnHeader1.Text = "Фамилия";

 columnHeader2.Text = "Имя";

 columnHeader3.Text = "E-mail";


 listView1.Columns.Add(columnHeader1);

 listView1.Columns.Add(columnHeader2);

 listView1.Columns.Add(columnHeader3);


 ListViewItem Contact1 = new ListViewItem("Иванов");

 Contact1.SubItems.Add("Иван");

 Contact1.SubItems.Add("ivan@ivanov.ru");


 ListViewItem Contact2 = new ListViewItem("Петров");

 Contact2.SubItems.Add("Петр");

 Contact2.SubItems.Add("peter@petrov.ru");


 ListViewItem Contact3 = new ListViewItem("Сидоров");

 Contact3.SubItems.Add("Арнольд");

 Contact3.SubItems.Add("goat@sidorov.ru");


 listView1.Items.Add(Contact1);

 listView1.Items.Add(Contact2);

 listView1.Items.Add(Contact3);

}

На рис. 3.12 показан внешний вид приложения со списком в виде таблицы.

Рис. 3.12. Пример работы с элементом ListView

В полной версии .NET Framework элемент управления

ListView
поддерживает свойство
MultiSelect
, позволяющее одновременно выбрать несколько элементов из списка. Версия .NET Compact Framework не поддерживает данное свойство, поэтому пользователь может выбрать только один элемент.

Элемент TabControl

Элемент управления

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

В устройствах Pocket PC вкладки располагаются в нижней части окна. Следует обратить внимание на то, что элемент

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

Элемент

TabControl
следует расположить на форме. У него по умолчанию будут созданы вкладки
tabPage1
и
tabPage2
. Если нужно добавить новую вкладку, то следует щелкнуть на маленькой стрелке в верхней части элемента
TabControl
и выбрать пункт меню
Add Tab
(рис. 3.13).

Рис. 3.13. Добавление новой закладки в элементе TabControl

В результате у элемента

TabControl
появится новая закладка, которую можно настроить в соответствии с потребностями разработчика. Также программист может воспользоваться услугами редактора
TabPage Collection Editor
для добавления новых закладок. В этом случае надо выбрать элемент
TabControl
в дизайнере формы, найти свойство
TabPages
и нажать кнопку редактирования этого свойства. В результате будет открыт редактор закладок. Для управления закладками можно также выделить
TabControl
, щелкнуть на нем правой кнопкой мыши и выбрать пункты контекстного меню
Add Tab
или
Remove Tab
.

Для определения текущей вкладки используется свойство

SelectedIndex
. При изменении данного свойства инициируется событие
SelectedIndexChanged
, что иллюстрирует код, приведенный в листинге 3.22.

Листинг 3.22

private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {

 switch (this.tabControl1.SelectedIndex) {

 case 0:

  MessageBox.Show("Вы выбрали первую вкладку");

  break;

 case 1:

  MessageBox.Show("Вы выбрали вторую вкладку");

  break;

 case 2:

  MessageBox.Show("Вы выбрали третью вкладку");

  break;

 }

}

Элемент TreeView

Элемент управления

TreeView
позволяет представить данные в иерархическом виде. Именно в этом виде отображается структура дисковой системы в левой части рабочего окна программы Проводник Windows. Основой элемента
TreeView
являются объекты
TreeNode
и
Nodes
. При работе с
TreeView
также широко используется элемент управления
ImageList
, используемый как хранилище изображений для узлов.

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

TreeView
. Затем следует выбрать свойство
Nodes
и запустить редактор
TreeNode Editor
. Кнопка
Add Root
отвечает за создание узлов дерева. Кнопка
Add Child
позволяет добавить дочерний узел к выбранному узлу. Кнопка
Delete
удаляет выбранный узел.

Чтобы задать текст, отображаемый в узлах, можно использовать свойство

Text
. Также в узлах можно использовать изображения, для чего применяется комбинация элемента управления
ImageList
и свойства
SelectedImageList
. Для определения текущего узла используется свойство
SelectedNode
.

На рис. 3.14 показан внешний вид приложения, использующего элемент интерфейса

TreeView
.

Рис. 3.14. Использование элемента TreeView

Элемент InputPanel

Элемент управления

InputPanel
позволяет вводить текстовую информацию при помощи виртуальной клавиатуры или панели распознавания знаков SIP (Soft Input Panel). Так как в полной версии .NET Framework данного элемента нет, то стоит рассмотреть его несколько подробнее.

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

ToolBar
. Тогда виртуальная клавиатура появится на экране, и пользователь сможет вводить текст.

Разработчик может программно управлять состоянием клавиатуры. Например, с помощью элемента

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

Bounds
— прямоугольник, определяющий размеры и позицию SIP.

VisibleDesktop
— прямоугольная часть экрана, на которой не отображается SIP.

Enabled
— возможность работы с SIP.

EnabledChanged
— событие, возникающее при изменении состояния SIP.

Свойства

Bounds
и
VisibleDesktop
доступны только для чтения и определяют прямоугольники, по которым можно судить о положении SIP и размерах клиентской области, не занятой SIP. Свойство
VisibleDesktop
определяет прямоугольник, которым ограничена область экрана, не закрытая SIP. Когда виртуальная клавиатура отображается, то условный прямоугольник поднимается от полоски навигации над окном SIP. Когда SIP скрыт, то прямоугольник занимает все пространство экрана.

Свойство

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

Свойство

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

Если в приложении необходимо использовать элемент

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

Можно размещать текстовые поля на форме как можно выше, чтобы элемент

InputPanel
не мешал вводить данные. Но помимо этого можно отслеживать состояние виртуальной клавиатуры и при ее отображении передвигать вверх поля для ввода информации. В этом случае чаще всего приходится применять полосы прокрутки. Можно проиллюстрировать такое поведение примером, в котором элемент
InputPanel
будет активироваться, если текстовое поле получит фокус. А когда
TextBox
потеряет фокус, то клавиатура должна исчезнуть. Эта функциональность реализуется кодом, приведенным в листинге 3.23.

Листинг 3.23

private void txtTest_GotFocus(object sender, EventArgs e) {

 // Когда пользователь выбирает текстовое поле.

 // то автоматически активируем SIP

 inputPanel1.Enabled = true;

}


private void txtTest_LostFocus(object sender, EventArgs e) {

 // При потере фокуса сворачиваем SIP

 inputPanel1.Enabled = false;

}

В этом примере пришлось добавить на форму кнопку, иначе текстовое поле будет автоматически получать фокус при загрузке формы и приложение не будет работать так, как это задумывалось изначально. В данном случае именно кнопка будет получать фокус ввода при загрузке формы. Но для этого надо присвоить свойству кнопки

TabIndex
нулевое значение.

Теперь если стилусом активировать текстовое поле, то автоматически будет отображена виртуальная клавиатура. Если на появившейся клавиатуре нажать клавишу

Tab
или щелкнуть на кнопке с надписью
Просто кнопка
, то панель ввода автоматически свернется.


Элемент

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

Листинг 3.24

private void inputPanel1_EnabledChanged(object sender,EventArgs e) {

 // Отслеживаем состояние панели ввода

 // Свойство Bounds возвращает размеры и позицию SIP

 if (inputPanel1.Enabled == true)

  this.txtJump.Top = 200 — inputPanel1.Bounds.Height;

 else

  this.txtJump.Top = 200;

}

На рис. 3.15 показан внешний вид окна тестового приложения.

Рис. 3.15. Пример работы с элементом InputPanel

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

Элемент управления DataGrid

Элемент управления

DataGrid
позволяет отображать данные в виде таблицы, как это сделано в электронной таблице MS Excel. Как и многие другие элементы управления, он имеет обрезанные возможности по сравнению с полной версией .NET Framework. Например, отключена поддержка свойства
DataMember
.

Элемент управления

DataGrid
может быть связан с источниками данных при помощи свойства
DataSource
. Рассмотрим простейший пример работы с данным элементом. Прежде всего, потребуется создать XML-файл, содержащий некоторые данные. Для примера был использован файл
artists.xml
, в котором содержится информация о некоторых известных артистов шоу-бизнеса. Файл содержит записи о фамилии, дате рождения и адресе проживания. Созданный файл нужно добавить в проект, расположить на форме элемент
DataGrid
и присвоить ему имя
grdArtists
. В листинге 3.25 приведен код обработчика события
Form1_Load
.

Листинг 3.25

private void Form1_Load(object sender, EventArgs e) {

 Cursor.Current = Cursors.WaitCursor;

 try {

  // Загружаем данные DataSet

  DataSet ds = new DataSet();

  ds.ReadXml(@"\Program Files\DataGrid_CS\artists.xml");

  grdArtists.DataSource = ds.Tables[0];

 } catch (Exception) {

  MessageBox.Show("Не могу загрузить данные в DataGrid!", this.Text);

 }


 // Устанавливаем стили

 DataGridTableStyle ts = new DataGridTableStyle();

 ts.MappingName = "Order";


 DataGridColumnStyle artistDate = new DataGridTextBoxColumn();

 artistDate.MappingName = "BirthDate";

 artistDate.HeaderText = "Дата рождения";

 ts.GridColumnStyles.Add(artistDate);


 DataGridColumnStyle artistName = new DataGridTextBoxColumn();

 artistName.MappingName = "ArtistName";

 artistName.HeaderText = "Артист";

 artistName.Width = this.Width - artistDate.Width - 35;

 ts.GridColumnStyles.Add(artistName);


 grdArtists.TableStyles.Add(ts);


 Cursor.Current = Cursors.Default;

}

В данном примере из XML-файла извлекаются данные, относящиеся к фамилии артиста и дате его рождения. Остальная информация игнорируется. При загрузке приложения в элемент

DataGrid
записываются требуемые данные. На рис. 3.16 показан внешний вид приложения.

Рис. 3.16. Пример работы с элементом DataGrid

Также стоит прочитать статью «Using the DataGrid Control in Pocket PC Applications», которую можно найти в справочной системе MSDN. В этой статье иллюстрируются различные приемы программирования, которые помогут расширить возможности данного элемента.

Элемент Splitter

Элемент управления

Splitter
появился только в .NET Compact Framework 2.0. В предыдущей версии его не было. Этот элемент реализует разделитель, который используется для изменения размеров закрепленных элементов управления во время выполнения программы. Элемент
Splitter
обычно используется вместе с элементами управления, содержащими данные переменной длины.

Стоит рассмотреть работу данного элемента на конкретном примере. На форме следует расположить графическое поле

PictureBox
и присвоить его свойству
Dock
значение
Top
. Затем на форме надо расположить объект
Splitter
и его свойству
Dock
тоже присвоить значение
Top
. Также следует расположить на форме текстовое поле
TextBox
. Его свойству
Multiline
надо присвоить значение
True
, а свойству
Dock
— значение
Fill
. Внешний вид получившегося приложения показан на рис. 3.17.

Рис. 3.17. Применение элемента Splitter в приложении

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

Элемент MonthCalendar

Элемент управления

MonthCalendar
появился только в последней версии .NET Compact Framework 2.0. Данный элемент позволяет легко выбрать необходимую дату.

Для создания тестового приложения на форме надо разместить элементы

MonthCalendar
и
Label
. Метка должна получить имя
lblSelectDate
, а для свойства
Text
нужно задать значение
Выбранная дата
. Затем следует дважды щелкнуть на элементе
monthCalendar1
, чтобы задать код обработчика события
DateChanged
. Этот код приведен в листинге 3.26.

Листинг 3.26

private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e) {

 lblSelectDate.Text =

  "Выбранная дата: " + monthCalendar1.SelectionStart.ToShortDateString();

}

Теперь можно запустить приложение и выбрать любую дату из месячного календаря. Выбранная дата будет автоматически отображаться в надписи

lblSelectDate
, как показано на рис. 3.18.

Рис. 3.18. Выбираем дату из месячного календаря

Элемент DateTimePicker

Элемент управления

DateTimePicker
также является новым элементом, который появился в .NET Compact Framework 2.0. Он позволяет выбирать не только дату, но и время.

На форме надо разместить элемент

DateTimePicker
и две текстовые метки
Label
, в которых будут отображаться дата и время. Затем нужно дважды щелкнуть на элементе
DateTimePicker
, чтобы задать код обработчика события
ValueChanged
. Этот код приведен в листинге 3.27.

Листинг 3.27

private void dateTimePicker1_ValueChanged(object sender, EventArgs e) {

 lblDate.Text = "Дата: " + dateTimePicker1.Value.ToShortDateString();

 lblTime.Text = "Время: " + dateTimePicker1.Value.ToShortTimeString();

}

Внешний вид получившегося приложения показан на рис. 3.19.

Рис. 3.19. Выбор даты при помощи элемента DateTimePicker

В документации MSDN есть небольшая статья «How to: Use the DateTimePicker Class in the .NET Compact Framework», в которой приводится небольшой пример использования этого элемента. Поддержка данного элемента появилась и в смартфонах под управлением Windows Mobile 5.0. Но в этом случае внешний вид элемента будет несколько иным.

Элемент DocumentList

Новый элемент управления

DocumentList
, который появился в .NET Compact Framework 2.0, может заменить такие элементы, как
SaveFileDialog
и
OpenFileDialog
, так как имеет все необходимые средства для работы с файлами. Помимо этого элемент
DocumentList
имеет дополнительные возможности, которые наверняка понравятся разработчикам программ. Он позволяет очень просто реализовать основные задачи манипулирования файлами, к которым относятся копирование, удаление, переименование и перемещение файлов. С помощью этого элемента также можно сортировать файлы по имени, дате создания, размеру. Кроме того, существует даже возможность посылать файлы по электронной почте или передавать на другое устройство при помощи инфракрасной связи.

Элемент

DocumentList
работает с файлами в пределах папки
My Documents
, включая подпапки. Следует обратить внимание на то, что
DocumentList
является классом из пространства
Microsoft.WindowsCE.Forms
и не является частью полной версии .NET Framework. Поэтому есть смысл поближе познакомиться с данным элементом.

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

DocumentList
. Для свойства
Name
надо задать значение
DocListFile
, свойство
Dock
должно получить значение
Top
, свойству
Height
присваивается значение 160, а для свойства
SelectedDirectory
задается значение
My Documents
.

Также на форме надо разместить элементы

ComboBox
и
StatusBar
. Элементу
ComboBox
надо присвоить имя
cboFileType
. Затем следует выбрать свойство
Items
и открыть окно редактора
String Collection Editor
. Для списка надо задать значения
BMP
и
WAV
.

Затем нужно дважды щелкнуть на элементе

ComboBox
, чтобы задать код обработчика события
SelectedIndexChanged
. Код обработчика приведен в листинге 3.28.

Листинг 3.28

private void cboFileType_SelectedIndexChanged(object sender, EventArgs e) {

 if (cboFileType.Text = "BMP") {

  docListFile.Filter = "Рисунки (*.bmp)|*.bmp";

  docListFile.SelectedDirectory = "My Pictures";

 } else {

  docListFile.Filter = "Звуки (*.wav)|*.wav";

  docListFile.SelectedDirectory = "My Music";

 }

}

Данный код динамически меняет значение свойства

Filter
элемента
DocumentList
для отображения файлов определенного типа. Также меняется папка просмотра файлов. Если пользователь выберет расширение
.BMP
, то следует выбрать папку
My Pictures
, специально предназначенную для хранения картинок. При выборе типа файлов
.WAV
выбирается папка
My Music
.

Теперь следует дважды щелкнуть на элементе

DocumentList
, чтобы создать обработчик события
DocumentActivated
. Соответствующий код приведен в листинге 3.29.

Листинг 3.29

private void docListFile_DocumentActivated(object sender,

 Microsoft.WindowsCE.Forms.DocumentListEventArgs e) {

 statusBar1.Text = e.Path;

 // работа с выбранным файлом

}

Перед началом тестирования стоит скопировать несколько соответствующих файлов в папки

My Pictures 
и
My Music
. После запуска программы нужно перейти в поле со списком и выбрать тип файлов. После этого будет активирован элемент
DocumentList
с выбранной папкой. Из списка документов можно будет выбрать конкретный файл.

Следует обратить внимание на то, что выбранный файл имеет контекстное меню при помощи которого можно выполнять базовые операции с файлом (рис. 3.20). Путь к выбранному файлу отображается в строке состояния.

Рис. 3.20. Выбор файла при помощи элемента DocumentList

Элемент Notification

Еще один новый элемент управления, который появился в последней версии .NET Compact Framework 2.0, носит имя

Notification
. Данный элемент управления позволяет отображать интерактивные сообщения. В документации по данному элементу приводится довольно интересный пример с использованием HTML-текста. Но в книге можно ограничиться более наглядным примером.

Для создания тестового примера нужно переместить на форму элементы

Notification
и
Button
. При нажатии на кнопку необходимо отобразить соответствующее сообщение. Это реализуется при помощи кода, приведенного в листинге 3.30.

Листинг 3.30

private void button1_Click(object sender, EventArgs e) {

 notification1.Text = "Позвони родителям!";

 notification1.Caption = "Демонстрация примера";

 notification1.Critical = true;


 // Уведомление висит на экране 10 секунд

 notification1.InitialDuration = 10;

 notification1.Visible = true;

}

На рис. 3.21 показано сообщение, которое будет отображаться на экране КПК в течение 10 секунд.

Рис. 3.21. Вывод сообщения с помощью элемента Notification

ПРИМЕЧАНИЕ

Элемент Notification применяется только в приложениях для карманных компьютеров. Смартфоны его не поддерживают.

Элемент HardwareButton

На карманных компьютерах кроме клавиш навигации присутствуют также дополнительные кнопки, при помощи которых активируются часто запускаемые приложения. Как правило, в состав программного обеспечения КПК входит утилита, с помощью которой можно назначить каждой из этих кнопок определенные команды. Но можно представить ситуацию, когда для создаваемой игры нужно, чтобы управление осуществлялось с помощью этих кнопок. Тогда необходимо переопределить на время поведение кнопок в вашем приложении. И сделать это можно с помощью элемента

HardwareButton
, который появился в .NET Compact Framework 2.0.

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

Component tray
два элемента
HardwareButton
с именами
hrdLeftRotate
и
hrdRightRotate
. Для каждой переопределяемой кнопки необходимо создать свой экземпляр элемента
HardwareButton
. В рассматриваемом примере будут переопределяться вторая и третья кнопки.

Также на форме надо разместить графическое поле

PictureBox
. В него надо загрузить любое изображение и растянуть картинку таким образом, чтобы она заняла верхнюю половину экрана. Изображение надо пристыковать к верхней части формы. Для этого свойству
Dock
присваивается значение
Top
. Также на форме надо разместить надпись
Label
, при помощи которой будут отображаться подсказки. Надпись следует пристыковать к нижней части формы. Для этого свойству
Dock
присваивается значение
Bottom
. У обоих добавленных элементов
HardwareButton
нужно отыскать свойство
AssociatedControl
и задать значение
Form1
. Также надо изменить значения свойств
HardwareKey
. Для первого элемента применяется значение
ApplicationKey2
, что соответствует второй кнопке. Для второго элемента задается значение
ApplicationKey3
, что соответствует третьей кнопке под экраном. Теперь, когда все необходимые свойства установлены, нужно написать код для события
Form1_KeyUp
. Код приведен в листинге 3.31.

Листинг 3.31

private void Form1_Load(object sender, EventArgs e) {

 label1.Text = "Нажмите вторую кнопку для поворота экрана на 90 градусов";

}


private void Form1_KeyUp(object sender, KeyEventArgs e) {

 switch ((HardwareKeys)e.KeyCode) {

 case HardwareKeys.ApplicationKey2:

  if (SystemSettings.ScreenOrientation == ScreenOrientation.Angle0) {

  SystemSettings.ScreenOrientation = ScreenOrientation.Angle90;

  label1.Text =

   "Нажмите третью кнопку для поворота экрана в первоначальную позицию";

  }

  break;

 case HardwareKeys.ApplicationKey:

  if (SystemSettings.ScreenOrientation == ScreenOrientation.Angle90) {

  SystemSettings.ScreenOrientation = ScreenOrientation.Angle();

  label1.Text = "Нажмите вторую кнопку для поворота экрана на 90 градусов";

  }

  break;

 default:

  break;

 }

}

Запустите программу и попытайтесь нажимать по очереди на вторую и третью кнопки под экраном карманного компьютера. Результат показан на рис. 3.22.

Рис. 3.22. Поворот экрана при помощи аппаратных кнопок

ПРИМЕЧАНИЕ

В документации говорится, что различные модели КПК имеют различное число кнопок, причем не все из них поддерживаются на системном уровне. Например, Windows Mobile 2003 для Pocket PC поддерживает четыре кнопки, a Windows Mobile 5.0 для Pocket PC поддерживает пять кнопок. При этом класс HardwareButton не поддерживается смартфонами и другими устройствами на базе Windows СЕ, которые не является устройствами Pocket PC.

Загрузка...