Главная » Разработка для Windows Phone 7 » TextBox и ввод с клавиатуры Windows Phone 7

0

В Silverlight для Windows Phone предлагается два типа элементов управления, обеспечивающих текстовый ввод. Это TextBox, который позволяет вводить и редактировать неформатированный текст в одну или много строк, и PasswordBox (Поле для введения пароля), который несколько мгновений показывает введенный символ и затем заменяет его другим символом, по умолчанию звездочкой.

Приложение может принимать ввод с аппаратной клавиатуры телефона (если таковая существует) или вызывать Software Input Panel (SIP), виртуальную экранную клавиатуру, только этими двумя способами.

Сразу перейдем к практике. Назначение приложения OneTimeText (Разовое текстовое сообщение) – отправка коротких текстовых сообщений SMS (Short Message Service)[12] на определенный телефонный номер. Приложение требует ввести этот телефонный номер, но нигде его не сохраняет. Поэтому я использовал в его имени слово «разовый» (one time).

Рассмотрим область содержимого:

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

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid Margin="24">

<Grid.RowDefinitions>

<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions>

<TextBlock Grid.Row="0"

Text="phone number"

Style="{StaticResource PhoneTextSmallStyle}" />

<TextBox Name="toTextBox" Grid.Row="1"

InputScope="TelephoneNumber" TextChanged="OnTextBoxTextChanged" />

<TextBlock Grid.Row="2"

Text="text message" HorizontalAlignment="Left"

Style="{StaticResource PhoneTextSmallStyle}" />

<TextBlock Name="charCountText" Grid.Row="2"

HorizontalAlignment="Right"

Style="{StaticResource PhoneTextSmallStyle}" />

<TextBox Name="bodyTextBox" Grid.Row="3" MaxLength="160" TextWrapping="Wrap"

VerticalScrollBarVisibility="Auto" TextChanged="OnTextBoxTextChanged" />

<Button Name="sendButton" Grid.Row="4" Content="send" IsEnabled="False" HorizontalAlignment="Center" Click="OnSendButtonClick" />

</Grid> </Grid>

Первый TextBox предназначен для ввода телефонного номера, поэтому ему достаточно одной строки. Второй TextBox – для ввода тела сообщения. Он занимает все пространство Grid, не используемое другими элементами. Его свойству TextWrapping задано значение

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

Кнопка с надписью «send» (отправить) изначально неактивна, потому что еще ничего не введено ни в один TextBox. По этой причине событие TextChanged (Текст изменен) задано для обоих TextBox.

Свойству InputScope (Тип вводимых данных) первого TextBox задано значение TelephoneNumber (Телефонный номер). Когда пользователь касается этого TextBox, появляется цифровая клавиатура:

Для второго TextBox свойство InputScope не задано, поэтому для него выводится стандартная клавиатура общего назначения:

Для второго TextBox задано свойство MaxLength, поэтому в него нельзя ввести более 160 символов – максимальная длина SMS.

Допустимые значения InputScope являются членами перечисления InputScopeNameValue (Имена типов вводимых данных), описанного в пространстве имен System.Windows.Input. Чтобы иметь возможность пользоваться подсказками Intellisense в Visual Studio, необходимо вынести InputScope как свойство-элемент и задать его следующим образом:

<TextBox Name="toTextBox" Grid.Row="1"

TextChanged="0nTextBoxTextChanged"> <TextBox.InputScope> <InputScope>

<InputScopeName NameValue="TelephoneNumber" /> </InputScope> </TextBox.InputScope> </TextBox>

Теперь сразу же после ввода знака равно за NameValue, система предложит список возможных вариантов значений.

В XAML нет самого важного свойства TextBox, каковым является свойство Text типа string. В любой момент времени программно можно выполнить доступ к этому свойству и получить или задать ему значение для инициализации содержимого. Также можно вставить что-то в существующее содержимое TextBox или удалить что-то. Операция удаления включает следующие этапы: получение текущего значения свойства Text, применение обычных методов класса String для создания новой строки, содержащей новый текст, и затем задание этой строки как нового значения свойства Text.

Привожу довольно большой фрагмент файла выделенного кода MainPage: Проект Silverlight: OneTimeText Файл: MainPage.xaml.cs (фрагмент)

public partial class MainPage : PhoneApplicationPage {

PhoneApplicationService appService = PhoneApplicationService.Current; SmsComposeTask smsTask;

public MainPage() {

InitializeComponent(); smsTask = new SmsComposeTask();

}

void 0nTextBoxTextChanged(object sender, TextChangedEventArgs args) {

if (sender == bodyTextBox)

charCountText.Text = String.Format("{0} chars", bodyTextBox.Text.Length);

sendButton.IsEnabled = toTextBox.Text.Length > 0 && bodyTextBox.Text.Length

> 0;

}

void 0nSendButtonClick(object sender, RoutedEventArgs e) {

smsTask.To = toTextBox.Text; smsTask.Body = bodyTextBox.Text; smsTask.Show();

}

Единственный обработчик события TextChanged может различать, какой из элементов TextBox сформировал событие, путем сравнения аргумента sender с именами, определенными в XAML-файле. Для второго TextBox выполняется обновление экрана и отображается количество введенных символов. Кнопка «send» остается неактивной, если один из TextBox пуст.

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

В некоторый момент пользователь может вернуться к приложению OneTimeText. Объект SmsComposeTask не возвращает никаких данных приложению, его вызвавшему – это задача выполнения, а не задача выбора – но было бы неплохо, если бы пользователь мог видеть ранее введенный текст. Для этого приложение перегружает методы OnNavigationFrom и OnNavigationTo, чтобы обеспечить сохранение и восстановление состояния приложения:

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

protected override void OnNavigatedFrom(NavigationEventArgs args) {

appService.State["toText"] = toTextBox.Text; appService.State["bodyText"] = bodyTextBox.Text;

base.OnNavigatedFrom(args);

}

protected override void OnNavigatedTo(NavigationEventArgs args) {

object text;

if (appService.State.TryGetValue("toText", out text)) toTextBox.Text = text as string;

if (appService.State.TryGetValue("bodyText", out text)) bodyTextBox.Text = text as string;

base.OnNavigatedTo(args);

}

Последним примером, который мы рассмотрим в данной главе, является приложение QuickNotes. Его задача – обеспечивать возможность быстрого ввода коротких заметок и гарантировать их сохранение без каких-либо явных операций сохранения или загрузки. По сути, это версия приложения Notepad (Блокнот) для Windows Phone 7, но QuickNotes может работать только с одним файлом.

Приложение также позволяет менять размер шрифта, поэтому в классе параметров приложения QuickNotesSettings (Параметры QuickNotes) имеется два открытых свойства, Text и FontSize, а также методы для сохранения и загрузки этих свойств в/из изолированного хранилища:

Проект Silverlight: QuickNotes Файл: QuickNotesSettings.cs

public class QuickNotesSettings {

public QuickNotesSettings() {

this.Text = ""; this.FontSize =

(double)Application.Current.Resources["PhoneFontSizeMediumLarge"];

public string Text { set; get; } public double FontSize { set; get; }

public static QuickNotesSettings Load() {

IsolatedStorageSettings isoSettings = IsolatedStorageSettings.ApplicationSettings; QuickNotesSettings settings;

if (!isoSettings.TryGetValue<QuickNotesSettings>("settings", out settings)) settings = new QuickNotesSettings();

return settings;

}

public void Save() {

IsolatedStorageSettings isoSettings = IsolatedStorageSettings.ApplicationSettings; isoSettings["settings"] = this;

}

}

Как и в приложении Jot, за сохранение, загрузку и предоставление этих параметров отвечает класс App:

Проект Silverlight: QuickNotes Файл: App.xaml.cs

public partial class App : Application {

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

public QuickNotesSettings AppSettings { set; get; }

private void Application_Launching(object sender, LaunchingEventArgs e) AppSettings = QuickNotesSettings.Load();

private void Application Activated(object sender, ActivatedEventArgs e) AppSettings = QuickNotesSettings.Load();

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

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

}

В XAML-файле создается многострочный TextBox, занимающий всю область содержимого. Кроме определения свойства TextWrapping, обеспечивающего возможность многострочного редактирования, в разметке задается значение true свойству AcceptsReturn (Допускает возврат строки). Благодаря этому по нажатию клавиши Enter будет выполняться переход на новую строку, что вполне соответствует требованиям, предъявляемым к данному

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

Проект Silverlight: QuickNotes Файл: MainPage.xaml

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBox Name="txtbox"

TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextChanged="OnTextBoxTextChanged" />

</Grid>

XAML-файл также включает ApplicationBar с двумя кнопками, которые я создал самостоятельно для увеличения и уменьшения размера шрифта:

Проект Silverlight: QuickNotes Файл: MainPage.xaml

<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar>

<shell:ApplicationBarIconButton IconUri="/Images/littleletter.icon.png"

Text="smaller font"

Click="OnAppBarSmallerFontClick" />

<shell:ApplicationBarIconButton IconUri="/Images/bigletter.icon.png"

Text="larger font"

Click="OnAppBarLargerFontClick" />

</shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>

Благодаря всем этим приготовлениям, сам файл кода для MainPage довольно мал и прост: Проект Silverlight: QuickNotes Файл: MainPage.xaml.cs

public partial class MainPage : PhoneApplicationPage {

QuickNotesSettings appSettings = (Application.Current as App).AppSettings;

public MainPage() {

InitializeComponent();

txtbox.Text = appSettings.Text; txtbox.FontSize = appSettings.FontSize;

}

void OnTextBoxTextChanged(object sender, TextChangedEventArgs args) {

appSettings.Text = txtbox.Text;

}

void OnAppBarSmallerFontClick(object sender, EventArgs args) {

txtbox.FontSize = Math.Max(12, txtbox.FontSize – 1); appSettings.FontSize = txtbox.FontSize;

}

void OnAppBarLargerFontClick(object sender, EventArgs args) {

txtbox.FontSize = Math.Min(48, txtbox.FontSize + 2);

appSettings.FontSize = txtbox.FontSize;

При любом изменении текста в TextBox метод OnTextBoxChanged (При изменении текстового поля) сохраняет новую версию в параметрах приложения. Два метода для увеличения и уменьшения размера шрифта тоже сохраняют новое значение и используют его для задания свойства FontSize элемента TextBox. На рисунке показано, как все это выглядит в действии:

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

Я немного поупражнялся с решением этой проблемы. Точка вставки доступна через свойство SelectionStart (Начало выбранной подстроки). Как следует из его имени, это свойство используется в связи с выбором текста. Также существует свойство SelectionLength (Длина выбранной подстроки), значение которого равно 0, если никакой текст не выбран. (Выполнять доступ к или задавать выбранный текст можно также с помощью свойства SelectedText (Выбранный текст).)

У TextBox также имеется событие SelectionChanged (Выбранная подстрока изменилась), поэтому QuickNotes, несомненно, может сохранять новое значение SelectionStart в параметрах приложения при каждом его изменении. Тогда вся задача сводится к заданию свойства SelectionStart, а также Text и FontSize в конструкторе MainPage.

Однако такой подход не вполне работоспособен. При запуске или возвращении к QuickNotes фокус ввода находится не на TextBox. Пользователь должен коснуться экрана, чтобы TextBox получил фокус, и начать вводить что-то. Но при касании экрана пользователь задает новую точку ввода!

Решение этой небольшой проблемы в программном задании фокуса ввода для TextBox. Чтобы сделать это в конструкторе MainPage, необходимо установить обработчик события Loaded:

txtbox.Focus();

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

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

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

По теме:

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