Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 158 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 18:

Пользовательские компоненты

Упражнение 3. Создание невизуального компонента-будильника AlarmClock (тревожные часы) с собственным событием

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

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

В классе также создается одноименный событию защищенный виртуальный метод, обычно с префиксом On, для генерации события при наступлении определенного происшествия. Этот метод называется методом диспетчеризации события ( event-dispatching method ). Метод диспетчеризации, перед генерацией события, должен проверять, существует ли хотя бы один зарегистрированный обработчик этого события, чтобы не адресоваться к нулевому обработчику. Он также устанавливает значения фактических аргументов, передаваемых обработчикам. При регистрации обработчика события в клиентском коде поддерживаются только операции += и -=.

Рассмотрим механизм работы событий на примере создания невизуального компонента AlarmClock (будильник), передающего оповещение по прошествии указанного времени. Хотя встроить подобный код внутрь самого приложения вовсе не сложно, создание такого компонента позволит отделить его от остального исходного кода и использовать многократно в других приложениях (а удачные компоненты можно и продавать). В качестве объекта, инициирующего генерацию нашего события, будем использовать экземпляр системного таймера, определенного библиотечным компонентом Timer.

  • Добавьте к проекту MyComponents новый файл с именем AlarmClock.cs типа Component
  • Переведите редактирование компонента AlarmClock в режим Design и двойным щелчком в панели Toolbox добавьте к компоненту экземпляр системного таймера Timer с именем timer1
  • Выделите объект timer1 и через панель Properties установите свойство Interval=1000
  • Переведите панель Properties в режим Events, установите для события Tick срабатывания системного таймера название обработчика TimerHandler и нажмите клавишу Enter

Оболочка добавит в файл AlarmClock.cs заготовку обработчика TimerHandler события срабатывания системного таймера

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
    
//-------------------------------------------------------------
// Часть 0 расположена в отдельном файле AlarmClock.Designer.cs
//-------------------------------------------------------------
    
// Часть 1
namespace MyCompany.MyComponents
{
    public partial class AlarmClock : Component
    {
    public AlarmClock()
    {
    InitializeComponent();
    }
    
    public AlarmClock(IContainer container)
    {
    container.Add(this);
    
    InitializeComponent();
    }
			
    // Обработчик события срабатывания системного таймера, созданного,
    // настроенного и зарегистрированного через визуальный конструктор.
    // Обработчик выполняется каждую секунду и проверяет, пришла ли пора
    // генерировать наше событие, на которое подпишется клиент компонента
    private void TimerHandler(object sender, EventArgs e)
    {
    }		
    }
}
Листинг 18.10 . Начальное содержимое класса компонента в файле AlarmClock.cs

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

  • Выделите заготовку обработчика в отдельную часть, которую мы заполним позднее
// Часть 4
namespace MyCompany.MyComponents
{
// Часть класса с определением обработчика события Tick 
// системного таймера System.Windows.Forms.Timer timer1
partial class AlarmClock
{
// Обработчик события срабатывания системного таймера, созданного,
// настроенного и зарегистрированного через визуальный конструктор.
// Обработчик выполняется каждую секунду и проверяет, пришла ли пора
// генерировать наше событие, на которое подпишется клиент компонента
private void TimerHandler(object sender, EventArgs e)
{
}
}
}
Листинг 18.11 . Обработчик события системного таймера в файле AlarmClock.cs
  • Добавьте в файл AlarmClock.cs часть класса, содержащую определения свойств компонента для его настройки как в режиме проектирования, так и выполнения
// Часть 2
namespace MyCompany.MyComponents
{
    // Часть класса с определением полей и свойств
    partial class AlarmClock
    {
        // Объявляем внутренние поля
        bool alarmFired = false; // Состояние будильника (запущен/незапущен)
        DateTime alarmTime = DateTime.Now; // Хранит время запуска будильника
    
        // Вложенный класс аргументов, доступных в обработчике
        // Расширяет библиотечный класс аргументов событий
        public class AlarmEventArgs : EventArgs
        {
            // Поле
            DateTime time;
    
            // Свойство
            public DateTime Time
            {
                get { return time; }
                set { time = value; }
            }
        }
    
        // Свойство возвращает текущее время компьютера
        public DateTime CurrentTime
        {
            get { return DateTime.Now; }
        }
    
        // Свойство для чтения и установки времени запуска будильника
        public DateTime AlarmTime
        {
            get { return alarmTime; }
            set
            {
                if (value != alarmTime)
                {
                    alarmTime = value;
                    alarmFired = false;
                }
            }
        }
    
        // Свойство для проверки состояния хода системного таймера, 
        // его остановки и запуска
        public bool Enabled
        {
            get { return timer1.Enabled; }
            set
            {
                timer1.Enabled = value;
                if (value)
                    alarmFired = false;
            }
        }
    }
}
Листинг 18.12 . Определение свойств в файле AlarmClock.cs
Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

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

 

Как активировать код?