Благодаря этим операторам связывание события TextChanged с обработчиками будет происходить уже после создания всех компонентов окна, и попытки обращения к неинициализированной метке не произойдет.
При анализе данного исправления возникает естественный вопрос: можно ли в программном коде связать требуемый обработчик с общим родителем обоих полей ввода – панелью StackPanel (подобно тому, как это делается в xaml-файле – см. комментарий 1)? Этому препятствуют два обстоятельства: во-первых, данная панель не имеет имени, с помощью которого к ней можно было бы обратиться в коде, и, во-вторых, в компоненте StackPanel отсутствует событие TextChanged. Первую проблему легко решить, добавив к описанию панели в xaml-файле атрибут x:Name. Вторая проблема решается благодаря наличию у любого компонента метода AddHandler, позволяющего связать с компонентом обработчик события даже в случае, если это событие для компонента не предусмотрено. Между прочим, первую из отмеченных проблем можно вообще не решать, если связать обработчик с родителем более высокого уровня – окном MainWindow. Таким образом, вместо указанных выше двух операторов достаточно добавить в конструктор окна следующий вызов метода AddHandler:
Обратите внимание на необходимость указания суффикса Event в первом параметре метода AddHandler и на более сложный способ определения второго параметра, требующий вызова конструктора класса, связанного с данным типом обработчиков событий.
4. Работа с датами и временем: CLOCK
Рис. 14. Окно приложения CLOCK
4.1. Отображение текущего времени
В список директив using в начале файла MainWindow.xaml.cs добавьте директиву:
В описание класса MainWindow добавьте поле
В конструктор класса добавьте следующие операторы:
Опишите в классе MainWindow обработчик события Tick для таймера (этот обработчик придется ввести полностью, вместе с его заголовком, так как заготовку для него нельзя создать с помощью окна Properties или xaml-файла):
Результат. При работе программы в ее окне отображается текущее время (рис. 15).
Рис. 15. Окно приложения CLOCK (первый вариант)
Комментарии
1. Для работы с датами и временем в библиотеке .NET предусмотрена структура DateTime. Ее статическое свойство Now, доступное только для чтения, возвращает текущую дату и время (по системным часам компьютера). Текущую дату без времени (время соответствует полуночи) можно получить с помощью статического свойства Today. Для преобразования даты/времени к их стандартным строковым представлениям можно использовать следующие методы структуры DateTime:
• ToShortDateString – дата в кратком формате «d», например «27.01.1756»;
• ToLongDateString – дата в полном формате «D», например «27 января 1756 г.»);
• ToShortTimeString – время в кратком формате «t», например «10:55»;
• ToLongTimeString – время в полном формате «T», например «10:55:15».
Метод ToString без параметров возвращает дату/время в формате «G» (дата в кратком формате, время в полном). Формат отображения даты/времени можно явно указать в методе ToString; например, в нашей программе можно было бы использовать такой вариант: DateTime.Now.ToString("T").
Упомянем еще некоторые форматы для даты/времени: «g» – дата и время в кратком формате, «F» – дата и время в полном формате, «f» – дата в полном формате, время в кратком, «M» или «m» – формат «месяц, день», «Y» или «y» – формат «месяц, год».
При форматировании дат используются текущие региональные настройки (в нашем случае – настройки для России), хотя имеется перегруженный вариант метода ToString, где можно явно указать требуемую региональную настройку. Можно также сменить региональную настройку для приложения в целом; для этого достаточно установить новое значение свойства CurrentCulture для объекта Thread.CurrentThread из пространства имен System.Threads. Например, для того чтобы установить для нашего приложения региональные настройки, соответствующие американскому варианту английского языка, достаточно добавить в конструктор следующий оператор: