Текст книги "Программирование мобильных устройств на платформе .NET Compact Framework"
Автор книги: Иво Салмре
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 43 (всего у книги 69 страниц)
Приведенный в листинге 13.1 код вносится в форму в проекте Pocket PC. Для создания и запуска приложения потребуется выполнить следующие действия:
1. Запустите Visual Studio .NET (2003 или более позднюю версию) и выберите в качестве типа приложения C# Smart Device Application.
2. Выберите в качестве целевой платформы Pocket PC. (Для вас будет автоматически создан проект, и на экране появится окно конструктора форм Pocket PC.)
3. Добавьте в форму перечисленные ниже элементы управления. Примечание. Пусть вас не волнуют точные размеры и расположение этих элементов управления; разместите их так, чтобы вам было удобно работать с ними на экране. Размеры и расположение элементов управления динамически изменяются во время выполнения приведенным ниже кодом пользовательского интерфейса.
• TextBox; переименуйте его в textBoxAskQuestion, установите значение true для его свойств MultiLine и ReadOnly.
• PictureBox; переименуйте его в pictureBoxGameBoard.
• Button; переименуйте его в buttonShowAnswers_AdvancedVersion.
• Button; переименуйте его в buttonShowAnswers_SimpleVersion.
• Button; переименуйте его в buttonAskQuestion.
• Button; переименуйте его в buttonAnswer0.
• Button; переименуйте его в buttonAnswer1.
• Button; переименуйте его в buttonAnswer2.
• Button; переименуйте его в buttonAnswer3.
• Button; переименуйте его в buttonAnswer4.
• Button; переименуйте его в buttonAnswer5.
4. Дважды щелкните на пустом участке формы в окне конструктора форм и введите приведенный ниже код Form_Load в автоматически сгенерированную и подключенную функцию обработчика событий.
5. Поочередно переходя от одной из вышеперечисленных кнопок Button к другой, щелкните на кнопке в окне конструктора форм. Введите приведенный ниже код button<ИмяКнопки>_Click в автоматически сгенерированную и подключенную функцию обработчика событий.
6. Введите оставшуюся часть приведенного ниже кода.
7. Установите для свойства MinimizeBox формы значение false. Благодаря этому во время выполнения приложения в верхней правой части формы появится кнопка OK, с помощью которой вы сможете легко закрыть форму и выйти из приложения. Эта возможность оказывается очень полезной при многократном тестировании приложения
8. В самом верху файла кода формы введите в качестве первой строки #define PLAYFIELD_ON_BOTTOM.
9. Дважды запустите приложение: один раз с подключенной директивой условной компиляции #define PLAYFIELD_ON_BOTTOM, а второй – с предварительным отключением этой же директивы при помощи символов комментария (то есть //#define PLAYFIELD_ON_BOTTOM), и отметьте для себя различия между двумя моделями компоновки. Запустите оба варианта на физическом устройстве и выясните, какая модель является более предпочтительной с точки зрения внешнего вида приложения и удобства работы с ним, а также возможностей обзора игрового поля.
10. Попробуйте изменить компоновку элементов управления по своему усмотрению. Вероятно, часть элементов управления пользовательского интерфейса имело бы смысл поместить выше игрового поля, а часть – ниже. Возможно, некоторые элементы должны располагаться поверх игрового поля, тогда как другие – справа или слева от него. Внося соответствующие изменения в код конечного автомата, вы легко сможете проверить и уточнить свои предположения.
Листинг 13.1. Использование конечного автомата для экспериментов с двумя различными вариантами компоновки пользовательского интерфейса
//–
//Конечный автомат, который управляет отображением кнопок, закрываемых рукой
//–
private enum GameUIState {
startScreen = 1,
waitForNextQuestion = 2,
waitForUserToStateKnowledge = 4,
waitForUserToAnswerMultipleChoice = 8
}
//Текущее состояние игры
private GameUIState m_GameUIState;
//==========================================================================
//Конечный автомат, используемый для управления пользовательским интерфейсом
//==========================================================================
private void StateChangeForGameUI(GameUIState newGameUIState) {
m_GameUIState = newGameUIState;
switch (newGameUIState) {
case GameUIState.startScreen:
buttonAskQuestion.Visible = true;
buttonAskQuestion.Text = "Start";
//Скрыть текстовое окно
textBoxAskQuestion.Visible = false;
SetAnswerButtonVisibility(false);
SetDifficultyButtonVisibility(false);
break;
case GameUIState.waitForNextQuestion:
setQuestionText("List answer details here... rn" +
"Lots of space to write...rn" +
"Waiting for user to select next question...");
textBoxAskQuestion.Visible = true;
buttonAskQuestion.Text = "Next";
buttonAskQuestion.Visible = true;
//Убедиться в том, что кнопка отображается на переднем плане
buttonAskQuestion.BringToFront();
SetAnswerButtonVisibility(false);
SetDifficultyButtonVisibility(false);
#if PLAYFIELD ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
textBoxAskQuestion.Height = pictureBoxGameBoard.Top – 2;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления
textBoxAskQuestion.Top = pictureBoxGameBoard.Top + pictureBoxGameBoard.Height + 2;
textBoxAskQuestion.Height = this.Height – textBoxAskQuestion.Top;
#endif
break;
case GameUIState.waitForUserToStateKnowledge:
SetTextForVocabularyQuestion();
textBoxAskQuestion.Visible = true;
buttonAskQuestion.Visible = false;
SetAnswerButtonVisibility(false);
SetDifficultyButtonVisibility(true);
#if PLAYFIELD_ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
textBoxAskQuestion.Height = buttonShowAnswers_AdvancedVersion.Top – 2;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления
textBoxAskQuestion.Top = buttonShowAnswers_AdvancedVersion.Top + buttonShowAnswers_AdvancedVersion.Height + 2;
textBoxAskQuestion.Height = this.Height – textBoxAskQuestion.Top;
#endif
break;
case GameUIState.waitForUserToAnswerMultipleChoice:
buttonAskQuestion.Visible = false;
SetDifficultyButtonVisibility(false);
//Сделать кнопки доступными, чтобы пользователь мог щелкать на них
SetAnswerButtonEnabled(true);
SetAnswerButtonVisibility(true);
#if PLAYFIELD_ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
textBoxAskQuestion.Height = buttonAnswer0.Top – 2;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления.
//Разместить текстовое окно таким образом, чтобы экран использовался
//эффективно
textBoxAskQuestion.Top = buttonAnswer5.Top + buttonAnswer5.Height + 2;
textBoxAskQuestion.Height =this.Height – textBoxAskQuestion.Top;
#endif
break;
//======================================================================
//Задать статическую компоновку нашего пользовательского интерфейса.
//Сюда входят все элементы, позиции которых остаются фиксированными.
//Изменения в остальные свойства внесет конечный автомат
//пользовательского интерфейса
//======================================================================
private void SetStartControlPositionAndState() {
pictureBoxGameBoard.Width = 240;
pictureBoxGameBoard.Height = 176;
//Установить размеры кнопок множественного выбора вариантов ответов
const int answerButtons_dx = 117;
const int answerButtons_dy = 18;
buttonAnswer0.Width = answerButtons_dx;
buttonAnswer0.Height = answerButtons_dy;
buttonAnswer1.Size = buttonAnswer0.Size;
buttonAnswer2.Size = buttonAnswer0.Size;
buttonAnswer3.Size = buttonAnswer0.Size;
buttonAnswer4.Size = buttonAnswer0.Size;
buttonAnswer5.Size = buttonAnswer0.Size;
buttonShowAnswers_AdvancedVersion.Width = answerButtons_dx;
buttonShowAnswers_AdvancedVersion.Height = 24;
buttonShowAnswers_SimpleVersion.Size = buttonShowAnswers_AdvancedVersion.Size;
//Расстояние (в пикселях) между соседними кнопками
const int dx_betweenButtons = 3;
const int dy_betweenButtons = 2;
const int answerbuttons_beginX = 3;
//Создать задний план для нашего изображения, чтобы мы видели
//его в процессе тестирования
System.Drawing.Bitmap gameBoard;
gameBoard = new System.Drawing.Bitmap(pictureBoxGameBoard.Width, pictureBoxGameBoard.Height);
System.Drawing.Graphics gameboard_gfx;
gameboard_gfx = System.Drawing.Graphics.FromImage(gameBoard);
gameboard_gfx.Clear(System.Drawing.Color.Yellow);
System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Blue);
gameboard_gfx.DrawRectangle(myPen, 2, 2, gameBoard.Width-4, gameBoard.Height-6);
myPen.Dispose();
gameboard_gfx.Dispose();
pictureBoxGameBoard.Image = gameBoard;
//Разместить текстовое окно, в котором содержатся задаваемые вопросы,
//a также подробные ответы для пользователей
textBoxAskQuestion.Left = 0;
textBoxAskQuestion.Width = 240;
buttonAskQuestion.Width = 64;
buttonAskQuestion.Height = 20;
#if PLAYFIELD_ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
const int answerbuttons_beginY = 42;
const int showanswers_beginY = 77;
//–
//Задать кнопки выбора вариантов Easy или Hard режима игры
//–
buttonShowAnswers_AdvancedVersion.Top = showanswers_beginY;
buttonShowAnswers_SimpleVersion.Top = showanswers_beginY;
//–
//Задать набор вариантов ответов
//–
//Задать элемент управления, по которому будут выравниваться
//все остальные элементы управления
buttonAnswer0.Top = answerbuttons_beginY;
//Поместить PictureBox под элементами управления
pictureBoxGameBoard.Top = (answerButtons_dy + dy_betweenButtons) * 3 + answerbuttons beginY;
buttonAskQuestion.Top = 0;
buttonAskQuestion.Left = 174;
textBoxAskQuestion.Top = 0;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления
const int answerbuttons_beginY = 174;
//–
//Задать кнопки выбора вариантов Easy или Hard режима игры
//–
buttonShowAnswers_AdvancedVersion.Top = answerbuttons_beginY;
buttonShowAnswers_SimpleVersion.Top = answerbuttons_beginY;
//–
//Задать набор вариантов ответа
//–
//Задать элемент управления, по которому будут выравниваться
//все остальные элементы управления
buttonAnswer0.Top = answerbuttons_beginY;
pictureBoxGameBoard.Top = 0;
buttonAskQuestion.Top = answerbuttons_beginY;
buttonAskQuestion.Left = 174;
#endif
buttonShowAnswers_AdvancedVersion.Left = answerbuttons_beginX;
buttonShowAnswers_SimpleVersion.Left = buttonShowAnswers_AdvancedVersion.Left + answerButtons_dx + dx betweenButtons;
pictureBoxGameBoard.Left = 0;
pictureBoxGameBoard.Width = 240;
pictureBoxGameBoard.Height = 172;
buttonAnswer0.Left = answerbuttons_beginX;
buttonAnswer1.Left = buttonAnswer0.Left + answerButtons_dx + dx_betweenButtons;
buttonAnswer1.Top = buttonAnswer0.Top;
//следующий ряд
buttonAnswer2.Left = buttonAnswer0.Left;
buttonAnswer2.Top = buttonAnswer0.Top + answerButtons_dy + dy_betweenButtons;
buttonAnswer3.Left = buttonAnswer2.Left + answerButtons_dx + dx_betweenButtons;
buttonAnswer3.Top = buttonAnswer2.Top;
//следующий ряд
buttonAnswer4.Left = buttonAnswer2.Left;
buttonAnswer4.Top = buttonAnswer2.Top + answerButtons_dy + dy_betweenButtons;
buttonAnswer5.Left = buttonAnswer4.Left + answerButtons_dx + dx_betweenButtons;
buttonAnswer5.Top = buttonAnswer4.Top;
}
//–
//Вспомогательная функция, которая позволяет задавать состояние
//видимости кнопок, отображающих ответы из словаря
//–
private void SetAnswerButtonVisibility(bool visibleState) {
buttonAnswer0.Visible = visibleState;
buttonAnswer1.Visible = visibleState;
buttonAnswer2.Visible = visibleState;
buttonAnswer3.Visible = visibleState;
buttonAnswer4.Visible = visibleState;
buttonAnswer5.Visible = visibleState;
}
//–
//Вспомогательная функция, вызываемая для задания свойств видимости
//некоторых элементов управления
//–
private void SetDifficultyButtonVisibility(bool visibleState) {
buttonShowAnswers_AdvancedVersion.Visible = visibleState;
buttonShowAnswers_SimpleVersion.Visible = visibleState;
}
//–
//Вспомогательная функция, которая позволяет задавать состояние
//видимости кнопок, отображающих ответы из словаря
//–
private void SetAnswerButtonEnabled(bool enabledState) {
buttonAnswer0.Enabled = enabledState;
buttonAnswer1.Enabled = enabledState;
buttonAnswer2.Enabled = enabledState;
buttonAnswer3.Enabled = enabledState;
buttonAnswer4.Enabled = enabledState;
buttonAnswer5.Enabled = enabledState;
}
//–
//Задает текст в текстовом окне и кнопках,
//необходимых для формулирования вопросов.
//
//B случае практической реализации эта функция должна просматривать
//вопросы динамически
//–
private void SetTextForVocabularyQuestion() {
setQuestionText("What is the English word for 'der Mensch'?");
buttonAnswer0.Text = "Four";
buttonAnswer1.Text = "Person";
buttonAnswer2.Text = "Three";
buttonAnswer3.Text = "To Jump";
buttonAnswer4.Text = "Newspaper";
buttonAnswer5.Text = "Brother";
}
//Вызывается для оценки варианта ответа, выбранного пользователем
private void evaluateMultipleChoiceAnswer(Button buttonClicked, int selection) {
//Примечание: в практической реализации правильный номер ответа
//определяется динамически и не всегда соответствует "кнопке № 1"
//Если выбранный пользователем вариант ответа не является правильным,
//отменить доступ к нажатой кнопке
if (selection ! = 1) {
//Выбранный вариант ответа является неправильным
buttonClicked.Enabled = false;
} else {
//Пользователь выбрал правильный ответ, продолжить игру
StateChangeForGameUI(GameUIState.waitForNextQuestion);
}
}
//Абстракция, задающая текст вопросов
void setQuestionText(string textIn) {
textBoxAskQuestion.Text = textIn;
}
//–
//ОБРАБОТЧИК СОБЫТИЙ: Пользователь желает увидеть следующий вопрос
//–
private void buttonAskQuestion_Click(object sender, System.EventArgs e) {
SetTextForVocabularyQuestion();
StateChangeForGameUI(GameUIState.waitForUserToStateKnowledge);
}
//–
//ОБРАБОТЧИК СОБЫТИЙ:
//Пользователь желает ответить на отображенный вопрос и сообщить, какой
//наиболее сложный уровень является для него приемлемым
//–
private void buttonShowAnswers_AdvancedVersion_Click(object sender, System.EventArgs e) {
//Установить состояние игры для отображения вариантов выбора
StateChangeForGameUI(GameUIState.waitForUserToAnswerMultipleChoice);
}
//–
//ОБРАБОТЧИК СОБЫТИЙ:
//Пользователь желает ответить на отображенный вопрос и сообщить, какой
//наиболее легкий уровень является для него приемлемым
//–
private void buttonShowAnswers_SimpleVersion_Click(object sender, System.EventArgs e) {
//Установить состояние игры для отображения вариантов выбора
StateChangeForGameUI(GameUIState.waitForUserToAnswerMultipleChoice);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer0_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer0, 0);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer1_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer1, 1);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer2_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer2, 2);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer3_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer3, 3);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer4_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer4, 4);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer5_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer5, 5);
}
//–
//ОБРАБОТЧИК СОБЫТИЙ: Вызывается при загрузке формы
//–
private void Form1_Load(object sender, System.EventArgs e) {
//Задать статические свойства нашего визуального интерфейса
SetStartControlPositionAndState();
//Задать динамические свойства, исходя из того, в какое состояние
//игры мы входим
StateChangeForGameUI(GameUIState.startScreen);
}
В случае мобильных приложений расположение элементов пользовательского интерфейса играет большую роль как в отношении удобства пользования ими, так и в отношении возможности представить полностью всю информацию, которая необходима. Лишь в редких случаях имеет смысл простой перенос пользовательского интерфейса с настольного компьютера на мобильное устройство; лично я не могу привести ни одного примера, когда бы это сработало на практике. Экранное разрешение и модели использования в этих двух случаях настолько радикально отличаются друг от друга, что попытки втиснуть пользовательский интерфейс и модель использования приложения, свойственные настольным компьютерам, в форм-фактор мобильного устройства – это рецепт неудачи. В лучшем случае вы получите неуклюжее посредственное приложение. Гораздо целесообразнее проанализировать, ранжировать по приоритетам и явно выписать перечень всех сценариев настольного компьютера, выполнение которых на мобильном устройстве является необходимым, а также сценариев, уникальных для мобильного устройства, которые вы хотели бы поддерживать, и лишь после этого создавать пользовательский интерфейс приложения, подчинив его вытекающим из всего вышесказанного требованиям.
To же самое можно сказать и о простом переносе приложения с одного устройства на другое, если их форм-факторы различны; такой "буквальный" перенос пользовательского интерфейса имеет смысл осуществлять лишь в редких случаях. Даже если большая часть логики приложения и может быть перенесена в неизменном виде, гораздо лучше составить явный перечень ключевых сценариев и специфических для устройства моделей использования и начать создавать пользовательский интерфейс, который удовлетворяет этим запросам, с нуля.
Экранное пространство – ценная вещьЧем меньше экран устройства, тем больше внимания необходимо уделять его эффективному использованию. Рациональное управление экранным пространством не имеет ничего общего с попытками разместить как можно больше элементов управления в пределах экрана; на самом деле почти всегда следует стремиться к обратному.
Физические возможности мобильных устройств ограничены, и поэтому вы не сможете разместить большинство элементов управления приложений для настольных компьютеров на экране мобильного устройства даже в том случае, если уменьшите шрифты наполовину, сведете размеры элементов управления до тех минимальных пределов, при которых ими еще можно пользоваться, и расположите их как можно ближе друг к другу так, как если бы они являлись элементами игры "Tetris". Ясно, что требуется совершенно иной подход. Наилучшие интерфейсы для мобильных устройств не страдают загруженностью экрана деталями, они разрежены и элегантны; как это ни парадоксально, создается впечатление, что имеющимся свободным пространством они могли бы еще и с кем-то поделиться. Вместо того чтобы пытаться разместить на экране мобильного устройства все элементы управления сразу, целесообразнее подойти к проблеме с другой стороны и задаться вопросом: "Каков тот абсолютный минимум информации и элементов управления, которые должны присутствовать на экране, чтобы пользователь имел возможность сделать следующий шаг?" Приступая к проектированию компоновки пользовательского интерфейса мобильного приложения, попытайтесь найти ответы на следующие вопросы:
■ Каков тот минимальный набор информации, которая должна отображаться на экране, и тот минимальный набор элементов управления, которые требуются для навигации? Можно ли дополнительно уменьшить этот набор путем разделения доступного экрана между несколькими менее насыщенными состояниями пользовательского интерфейса, которые могут отображаться по отдельности?
■ Должны ли размеры элементов управления изменяться при переходе от одного состояния пользовательского интерфейса к другому? Часто оказывается желательным сократить или увеличить размеры элемента пользовательского интерфейса, чтобы скрыть или показать более подробную информацию, если это позволяют размеры экрана.
■ Не будет ли эффективнее привлечь пользовательский элемент управления для отображения той информации, которая в настоящее время представляется несколькими элементами управления? Такое решение должно быть тщательно взвешено. Создание специализированного элемента управления может оказаться неплохим способом повышения эффективности использования пространства пользовательского интерфейса, но при этом следует проанализировать, насколько такое решение будет удовлетворительным с учетом следующих факторов: 1) разработка пользовательского элемента управления требует намного больших усилий, чем использование уже существующих и протестированных элементов управления, и 2) создание новой метафоры пользовательского интерфейса может затруднить его использование. Конечные пользователи уже знают, как использовать существующие элементы управления, тогда как к любым вновь введенным вами концепциям им придется привыкать. Тем не менее, в некоторых случаях такая работа является оправданной и может давать впечатляющие результаты.
Местоположение, местоположение и еще раз местоположение
Не все участки экрана равнозначны. Элемент управления, размещенный вверху, внизу, слева, справа или посередине экрана будет обладать различными свойствами применимости. Эти свойства часто меняются при переходе от одного класса устройств к другому. Так, элементы управления Pocket PC, принимающие текстовый ввод, следует размещать в верхней части экрана, поскольку в этих устройствах предусмотрена всплывающая программная клавиатура (SIP), которая, если вам необходимо ввести текст, отображается в нижней части экрана. Расположением элементов управления, которые вы размещаете на экране, должны управлять следующие два фактора:
1. Стиль и практика применения, существующие для вашего целевого мобильного устройства. Для большинства программируемых мобильных устройств существуют рекомендации, относящиеся к стилю компоновки пользовательского интерфейса. Эти рекомендации важно учитывать как для того, чтобы ваше приложение хорошо сочеталось с методами ввода, предусмотренными в устройстве (например, кнопки, сенсорный экран, всплывающая клавиатура), так и для того, чтобы все используемые на устройстве приложения имели унифицированный внешний вид и вели себя одинаковым образом с точки зрения пользователя. Если вы еще не успели прочитать эти рекомендации, обязательно сделайте это. Подобные рекомендации будут иметь для вас гораздо более высокую ценность, чем любой другой совет, касающийся общих вопросов компоновки интерфейсов.Примечание. Тот факт, что для каждого из различных классов устройств существуют свои рекомендации относительно стиля компоновки пользовательского интерфейса, является дополнительной причиной того, что модели, основанные на принципе "пишется однажды – выполняется везде", обычно не срабатывают. Все дело в том, что очень трудно создать единую унифицированную среду пользовательского интерфейса, которая бы автоматически и одинаково хорошо соответствовала стилевым рекомендациям для различных устройств.
2. Тестирование применимости модели на реальных устройствах. Окончательным арбитром применимости вашего пользовательского интерфейса является реальный пользователь, который использует его на реальном устройстве (не на эмуляторе). Поскольку мобильными устройствами пользуются, удерживая их в руках, например, на улице, в поезде, самолете или в битком набитом людьми лифте, ничто не способно заменить тестирование приложения на том реальном оборудовании, для которого оно предназначено, и в реальных условиях его использования.
Выбирайте соответствующие элементы управления для соответствующих устройств
Наряду с необходимостью следовать соответствующему стилю и рекомендациям относительно компоновки интерфейса для данного мобильного устройства очень важно правильно выбрать набор элементов управления, который хорошо подходит для вашего целевого устройства. Мобильная среда выполнения может поддерживать самые разнообразные элементы управления пользовательского интерфейса, однако лишь некоторые из них будут пригодны для использования на интересующем вас устройстве. Например, поскольку в смартфонах отсутствуют сенсорные экраны или указатели мыши, которыми вы могли бы воспользоваться для произвольного доступа к таким навигационным элементам управления, как вкладки, обычные кнопки и переключатели, то перечисленные элементы не могут служить полезной метафорой пользовательского интерфейса для этих устройств. Вместо этого для смартфонов хорошо подойдут списки и меню. Вообще говоря, чем меньше размеры устройства, тем специфичнее требования к элементам управления, которые могут применяться на этом устройстве.
Когда целесообразнее использовать различные формы, а когда – осуществлять смену элементов управления
Для облегчения навигации в пределах пользовательского интерфейса можно использовать два способа: 1) вызывать новые формы в ответ на действия пользователя, и 2) показывать или скрывать элементы управления на единственной форме. Оба эти способа могут служить механизмами показа пользователю нового экрана, заполненного информацией.
Вы не сделаете ничего плохого, если для манипулирования информацией, требующей нескольких экранов, используете одну-единственную форму, и будете показывать на ней и скрывать элементы управления в соответствии с необходимостью. Вы должны хранить такие многоэкранные элементы пользовательского интерфейса в одной форме в том случае, если они представляют родственные понятия и вам может потребоваться настройка связей между ними. Переместить информацию с одного "экрана" на другой легче, если управление ими реализовано в пределах одного и того же класса.
Разделять же функциональность между различными формами следует тогда, когда она действительно состоит из различных частей, а вероятность того, что в процессе настройки пользовательского интерфейса вы захотите переносить его элементы из одной формы в другую, мала. Эта мера позволяет уменьшить скученность элементов управления на экране.
Если экран вашего целевого мобильного устройства достаточно большой, то в качестве промежуточного решения, позволяющего добиться определенного компромисса, могут использоваться вкладки. Обычно каждую отдельную вкладку следует концептуально рассматривать как отдельную форму. Использование вкладок обладает тем замечательным преимуществом, что при этом вы не должны отображать или скрывать каждый экран вручную; это автоматически делает за вас среда выполнения. Рассмотрите возможность помещения кода обработчиков событий для содержимого каждой из вкладок в отдельные классы. Тем самым будет обеспечена надежная инкапсуляция кода, делающая его менее запутанным.







