Создаем собственное событие в C#

Задача: создать событие в своем классе, на которое можно подписаться извне и которое будет происходить при определенных условиях.

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

Итак, мы пишем компьютерную игру. В игре есть персонаж-герой, у него есть жизнь, измеряемая числом от 1 до 100. В результате сражений жизнь может изменяться. При изменении жизни надо обновлять число на экране, если жизнь становится меньше 20, выводить предупреждение.

public class Hero
{

// описание события
public event HealthChangedHandler HealthChanged;  

// делегат для подписывающихся на событие обработчиков 
public delegate void HealthChangedHandler(object sender, EventArgs eventArgs);

private int _health = 100;
public int Health 
{
	get
	{
		return _health;
	}
	set
	{
		_health = value;
		// если на событие не подписан ни один обработчик, здесь будет null 
		if (HealthChanged != null)
		{
			EventArgs eventArgs = new EventArgs();
			HealthChanged(this, eventArgs);
		}
	}
}

}

предположим, что игра происходит в окне Windows Forms (в жизни бывает еще и не такое) c текстовой меткой _heroHealthLabel и кнопкой _damageHeroButton
EventTest

public partial class GameForm : Form
{

private Hero _hero = null;

public GameForm()
{
	InitializeComponent();
	_hero = new Hero();
	_hero.HealthChanged += new Hero.HealthChangedHandler(_hero_HealthChanged);
}

private void _damageHeroButton_Click(object sender, EventArgs e)
{
	// уменьшаем жизнь на случайное значение от 10 до 20
	Random random = new Random();
	_hero.Health = _hero.Health - random.Next(10, 20);
}

void _hero_HealthChanged(object sender, EventArgs eventArgs)
{
	// так как в качестве параметром передан базовый класс EventArgs, означающий отсутствие параметров, цифру придется читать напрямую из переменной героя
	_heroHealthLabel.Text = _hero.Health.ToString();
	if(_hero.Health <= 20 && _hero.Health > 0)
	{
		MessageBox.Show("Вы скоро умрете. Удачного вам дня!");
	}

	if(_hero.Health <= 0)
        {
        	MessageBox.Show("Поздравляем, вы умерли! Наша игра - самая лучшая игра в мире!");
        }
}
}

Чтобы передавать обработчику события параметры нам надо создать свой класс параметров, наследующий от EventArgs, в вышеприведенный код добавится следующее (в учебных целях сохраним старое событие и исправление добавим новым, улучшенным событием:

public class HealthChangedArgs : EventArgs
{
        private int _health = 0;

        public int Health
        {
            get { return _health; }
        }

        public HealthChangedArgs(int health)
        {
            _health = health;
        }

}

// в свойство Health

set
{
	_health = value;
	// если на событие не подписан ни один обработчик, здесь будет null 
	if (HealthChanged != null)
        {
        	EventArgs eventArgs = new EventArgs();
                HealthChanged (this, eventArgs);

                // второй вариант события, в котором обработчику передаются параметры
                HealthChangedArgs healthChangedArgs = new HealthChangedArgs ( _health );
                HealthChangedPlus( this, healthChangedArgs );
	}
}

// в конструктор формы

_hero.HealthChangedPlus += new Hero. HealthChangedPlusHandler( _hero_HealthChangedPlus );

// в форму обработчик, использующий добавленный в дизайнере текстбокс

void _hero_HealthChangedPlus(object sender, HealthChangedArgs healthChangedArgs)
{
	_heroHealthTextBox.Text = healthChangedArgs. Health. ToString();
} 

// последний штрих, если мы делаем управлятор (Control), то новое свойство неплохо бы видеть в дизайнере, для Visual Studio это делается следующим образом

[Browsable(true)]
public event HealthChangedHandler HealthChanged;  

Если вы все еще не уверены в своих знаниях, можете скачать тестовый WinForms проект, созданный в VisualStudio 2010

EventTest.zip, 46 килобайт

Creating Custom Events in C#


Комментарии

Создаем собственное событие в C# — Комментарии (9)

    • By the way, K.Olbermann, spare me your seftr-ighlous crap about our 4,000 American brethren dying for Bush's cause. This war may have been wrong and clumsy from the start, but their sacrifice has helped make this world a better place. You won't say it out loud but you want us viewers to see their deaths as unnecessary. Just so you can throw rocks at Bush.Screw you, pompous jerk!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>