Главная · Карта сайта · Поиск · Статьи · Компьютерные курсы · Обучающие программы · Открытые проекты · Веб-программирование · Создание интернет-сайта · Полезные ссылки · Глоссарий · Контакты · Декабрь 06 2016 22:53:41
Последнее опубликованное

Что такое Model-View-Controller
Pattern Model-View-Controller

Как создать свой веб-сайт
Как создать свой сайт в интернете

Разное
Статистика

Программирование на C#. События


[Назад] [Следующая страница]

4.3.События

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

using System;
using System.Windows.Forms;
namespace CSharpQuickGuide
{
    //Делегат, определяющий сигнатуру события
    public delegate void MyEventDelegate(string _eventParameters);
    public class MyClassWithEvent
    {
        //Открытое событие
        public event MyEventDelegate MyEvent;
        //Обычно метод, отвечающий за возбуждение события делают
        //виртуальным и доступным только для производных классов с тем,
        //чтобы исключить несанкционированное возбуждение событий из вне
        //и позволить производным классам переопределять его поведение
        protected virtual void OnMyEvent(string _MyEventParameters)
        {
            if (MyEvent != null)
                MyEvent(_MyEventParameters);
        }
        //Метод, вызывающий событие
        public void DoSomething()
        {
            OnMyEvent("DoSomething");
        }
        //Еще один метод, вызывающий событие
        public void DoSomethingMore()
        {
            OnMyEvent("DoSomethingMore");
        }
    }
    //Пример обработки событий
    public static class EventSample
    {
        //Обработчик события
        public static void MyEventHandler(string _parameters)
        {
            MessageBox.Show(_parameters, "MyEventHandler");
        }
        //Еще один обработчик события
        public static void MyEventHandler2(string _parameters)
        {
            MessageBox.Show(_parameters, "MyEventHandler2");
        }

        public static void Test()
        {
            MyClassWithEvent myClass = new MyClassWithEvent();
            //Добавляем обработчик события
            myClass.MyEvent += new MyEventDelegate(MyEventHandler);
            //Вызываем метод, вызывающий событие
            myClass.DoSomething();
            //Удаляем обработчик из коллекции обратных вызовов
            myClass.MyEvent -= MyEventHandler;
            //Добавляем другой обработчик по упрощенной схеме
            //(без явного создания делегата)
            myClass.MyEvent += MyEventHandler2;
            //Вызываем второй метод, вызывающий событие
            myClass.DoSomethingMore();
        }
    }
}

Результатом работы приведенного кода будет последовательное появление сообщений “DoSomething” и “DoSomethingMore” с заголовками “MyEventHandler” и “MyEventHandler2” соответственно.

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

using System;
using System.Windows.Forms;
namespace CSharpQuickGuide
{
    public class MyClassWithEvent
    {
        //Скрытый от внешнего мира делегат
        private MyEventDelegate MyEvent;
        //Добавление ссылки на обратный вызов
        public void add_MyEvent(MyEventDelegate _delegate)
        {
            MyEvent += _delegate;
        }
        //Удаление ссылки на обратный вызов
        public void remove_MyEvent(MyEventDelegate _delegate)
        {
            MyEvent -= _delegate;
        }
        protected virtual void OnMyEvent(string _MyEventParameters)
        {
            if (MyEvent != null)
                MyEvent(_MyEventParameters);
        }
        public void DoSomething()
        {
            OnMyEvent("DoSomething");
        }
        public void DoSomethingMore()
        {
            OnMyEvent("DoSomethingMore");
        }
    }
    public static class EventSample
    {
        public static void MyEventHandler(string _parameters)
        {
            MessageBox.Show(_parameters, "MyEventHandler");
        }
        public static void MyEventHandler2(string _parameters)
        {
            MessageBox.Show(_parameters, "MyEventHandler2");
        }

        public static void Test()
        {
            MyClassWithEvent myClass = new MyClassWithEvent();
            //Добавляем обработчик события
            myClass.add_MyEvent(new MyEventDelegate(MyEventHandler));
            //Вызываем метод, вызывающий событие
            myClass.DoSomething();
            //Удаляем обработчик из коллекции обратных вызовов
            myClass.remove_MyEvent(MyEventHandler);
            //Добавляем другой обработчик по упрощенной схеме
            //(без явного создания делегата)
            myClass.add_MyEvent(MyEventHandler2);
            //Вызываем второй метод, вызывающий событие
            myClass.DoSomethingMore();
        }
    }
}

Результат работы этого кода аналогичен описанному ранее результату. Как видно из примера, делегат, хранящий указатели на методы обратного вызова скрыт от “внешнего мира”, и “доступ к телу” осуществляется только через два метода, добавляющих и удаляющих ссылки на обработчики событий. Инкапсуляция – это один из столпов объектно-ориентированного программирования, а создатели .NET тщательно следят за тем, чтобы CLR исполняемые языки соответствовали этой парадигме.

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

using System;
using System.Windows.Forms;
namespace CSharpQuickGuide
{
    //Класс, позволяющий хранить параметры события и расширяющий 
    //возможности базового класса BCL
    public class MyEventArgs : EventArgs
    {
        //Параметры события
        private string m_EventArgs;
        //Конструктор по умолчанию
        public MyEventArgs(string _EventArgs)
        { m_EventArgs = _EventArgs; }
        //Переопределение функции ToString()
        public override string ToString()
        {
            return m_EventArgs;
        }
    }
    public class MyClassWithEvent
    {
        //Использование универсального делегата
        public event EventHandler<EventArgs> MyEvent;
        //Возбуждение события
        protected virtual void OnMyEvent(EventArgs _MyEventParameters)
        {
            if (MyEvent != null)
                MyEvent(this, _MyEventParameters);
        }
        public void DoSomething()
        {
            OnMyEvent(new MyEventArgs("DoSomething"));
        }
        public void DoSomethingMore()
        {
            OnMyEvent(new MyEventArgs("DoSomethingMore"));
        }
    }
    public static class EventSample
    {
        public static void MyEventHandler(object sender, EventArgs e)
        {
            MessageBox.Show(e.ToString(), "MyEventHandler");
        }
        public static void MyEventHandler2(object sender, EventArgs e)
        {
            MessageBox.Show(e.ToString(), "MyEventHandler2");
        }

        public static void Test()
        {
            MyClassWithEvent myClass = new MyClassWithEvent();
            //Добавляем обработчик события
            myClass.MyEvent += new EventHandler<EventArgs>(MyEventHandler);  
            //Вызываем метод, вызывающий событие
            myClass.DoSomething();
            //Удаляем обработчик из коллекции обратных вызовов
            myClass.MyEvent -= MyEventHandler;
            //Добавляем другой обработчик по упрощенной схеме
            //(без явного создания делегата)
            myClass.MyEvent += MyEventHandler2;
            //Вызываем второй метод, вызывающий событие
            myClass.DoSomethingMore();
        }
    }
}

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



[Назад] [Следующая страница]

Компьютерные курсы и курсы программирования
Основы программирования

Курс для начинающих программистов на C# и VB.NET.

SQL 25™

Построение SQL запросов и работа с базой данных.

C# Quick Guide™

Программирование на C#. Краткое руководство.

RegEx

Применение регулярных выражений.

Plug-in архитектура

Примеры программной Plug-in архитектуры.

XML и его расширения

Язык разметки XML и его расширения с примерами.

HTML и разметка гипертекста

Языки HTML, XHTML и CSS с примерами разметки.

Основы веб-дизайна

Основы веб-дизайна: решения типовых задач верстки.

Программирование на PHP

Руководство по программированию на PHP для начинающих.

Справочные материалы

Шаблоны проектирования
Каталог шаблонов проектирования программных компонентов.

Рефакторинг кода
Каталог приемов рефакторинга программного кода.

Гость
Имя

Пароль



Забыли пароль?
Запросите новый здесь
.
Coding Craft. Все права защищены © 2011. Проект Инициативного Народного Фронта Образования - ИНФО-проект.