Опубликован: 11.09.2006 | Уровень: специалист | Доступ: платный
Лекция 1:

Введение в windows-формы

Лекция 1: 12345678910 || Лекция 2 >

События в Windows-приложениях

Теперь, когда мы разобрались с синтаксисом и логикой делегатов и событий, настало время приступить к рассмотрению событийной модели Windows-форм.

Откройте снова приложение FirstForm. Из окна Toolbox перетащите элемент управления Button на форму. Дважды щелкните на кнопке button1. В коде найдите область Windows Form Designer generated code. В таблице 1.3 сравниваются листинги приложений Event и FirstForm c кнопкой.

Таблица 1.3.
Консольное приложение Event Windows-приложение FirstForm
using System;
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Event
{
//Объявляем делегат Mydelegate
delegate void Mydelegate();
//Создаем класс Button, в котором 
//будет находится событие 
//и метод  для него
class Button
{
// Объявляем событие Sobitie 
// на основе делегата
public event Mydelegate Sobitie;
//Cоздаем метод для события, 
//который просто будет 
//обращаться к событию
public void MetoddlyaSobitiya()
{
  //Можно вставить проверку наличия события. 
  //if (Sobitie !=null)
  Sobitie();
}
class Class1
{
namespace FirstForm
{
	
public class Form1 : System.Windows.Forms.Form
{
  private System.Windows.Forms.Button button1;
	
private System.ComponentModel.Container 
  components = null;
		
public Form1()
{
			
InitializeComponent();
			
}

protected override void Dispose(bool disposing)
{
	if( disposing )
{
	if (components != null) 
{
	components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
	
private void InitializeComponent()
{
// Среда автоматически создает экземпляр 
// button1 класса Button при перетаскивании 
// элемента управления на форму
this.button1 = 
      new System.Windows.Forms.Button();
this.SuspendLayout();
// 
// button1
// 
this.button1.Location = 
      new System.Drawing.Point(104, 144);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
// Среда автоматически привязывает 
// обработчик для события Click экземпляра 
// button1. EventHandler – это делегат.
this.button1.Click += 
 new System.EventHandler(this.button1_Click);
// 
// Form1
// 
this.AutoScaleBaseSize = 
      new System.Drawing.Size(5, 13);
this.ClientSize = 
      new System.Drawing.Size(292, 266);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Fom1";
this.ResumeLayout(false);

}
#endregion
[STAThread]
static void Main(string[] args)
{
 // Создаем экземпляр btn класса Button
 Button btn = new Button();
 //привязываем обработчик для события 
 //Sobitie экземпляра btn.
 //Когда в скобках укажете 
 //Metodobrabotchik, нажмите 
 //дважды клавишу Tab
 btn.Sobitie += 
       new Mydelegate(Metodobrabotchik);
 //Развернутая запись строки выше
 //btn.Sobitie =  btn.Sobitie + 
 //     new Mydelegate(Metodobrabotchik);
 //вызываем метод для события
 btn.MetoddlyaSobitiya();
}
[STAThread]
static void Main() 
{
Application.Run(new Form1());
}
// Создаем метод-обработчик, если среда 
// сгенерировала его сама – 
// добавляем строку вывода.
private static void Metodobrabotchik ()
{
 Console.WriteLine("Произошло событие");
}
}
}
}
// Метод-обработчик для нажатия на кнопку; 
// когда мы щелкаем по элементу управления 
// в режиме дизайна, среда генерирует этот
//метод и курсор оказывается уже здесь
private void button1_Click(object sender, 
           System.EventArgs e)
{
MessageBox.Show("Произошло событие");
}
}
}

Сравнивая листинги, замечаем, что для Windows-приложения First Form не нужно объявлять делегат, событие, метод для обращения к событию и затем вызывать этот метод. Почему же это тогда работает? Дело в том, что среда .NET содержит огромное количество встроенных событий, доступ к которым осуществляется по их названиям. Более того, среда сама привязывает обработчика для события Click (нажатие на кнопку) и нужный метод, используя встроенный делегат EventHandler:

this.button1.Click += new System.EventHandler(this.button1_Click);

Платформа .NET требует точной сигнатуры для любого обработчика событий. button1_Click () и все остальные обработчики событий обязаны выглядеть следующим образом:

void button1_Click (object sender, EventArgs e)//е также может быть производным от EventArgs
{
// код для обработки события
}

Обработчики событий не могут возвращать ничего, кроме void. В них отсутствует точка, которая могла бы служить для возврата значения. Обработчики должны принимать два параметра. Первый параметр является ссылкой на объект, который сгенерировал событие. Второй параметр должен быть ссылкой либо на базовый класс .NET System.EventArgs, либо на производный класс. Класс EventArgs представляет собой общий базовый класс для всех уведомлений о произошедших событиях.

В окне свойств каждого элемента управления на вкладке событий перечислены все доступные события для этого элемента (рис. 1.39).

Вкладка событий элемента button в окне свойств Properties

Рис. 1.39. Вкладка событий элемента button в окне свойств Properties

Двойной щелчок в поле выбранного свойства перемещает нас в режим дизайна, где уже сгенерированы все объекты для обработки данного события и нам остается только написать код для метода-обработчика. На рис. рис. 1.39 выбрано событие Click, это же событие выбирается по умолчанию при двойном щелчке на элементе управления "кнопка".

События мыши

В Интернете часто встречается шуточная программка, представляющая собой диалоговое окно с двумя кнопками. Для ответа на предлагаемый вопрос следует нажать на одну из двух кнопок, причем вторая кнопка при наведении на нее курсора начинает "убегать" от него. Вы можете встретить реализацию этой шутки, написанную на многих языках — от C до Flash-приложений. Сделаем что-то подобное на C#. Создаем новое Windows-приложение и называем его SocOpros. Из окна Toolbox перетаскиваем на форму две кнопки Button и надпись Label. Устанавливаем следующие свойства элементов управления и формы:

Form1, форма, свойство Значение
FormBorderStyle Fixed3D
Icon ICOПуть E:\Program Files\Microsoft Visual Studio .NET2003\Common7\Graphics\icons\Computer\W95MBX02.ICO
Size 344; 176
Text Социологический опрос
label1, свойство Значение
Size 12
Bold true
Location 32; 28
Size 272; 32
Text Вы довольны своей зарплатой?
Button1, свойство Значение
Name btnyes
Location 67; 92
Text Да
Button2, свойство Значение
Name btnno
Location 195; 92
Text Нет

Щелкаем дважды по кнопке "Да". В обработчике этой кнопки вставляем следующий код:

private void btnyes_Click(object sender, System.EventArgs e)
{
	MessageBox.Show("Мы и не сомневались, что Вы так думаете!");
}

Выделяем кнопку "Нет". Открываем окно Properties. Переключаемся в окно событий и дважды щелкаем в поле MouseMove (рис. 1.40).

Событие MouseMove для кнопки btnno Надпись на информационной панели — "Происходит, когда мышь перемещается"

Рис. 1.40. Событие MouseMove для кнопки btnno Надпись на информационной панели — "Происходит, когда мышь перемещается"

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

private void btnno_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
		btnno.Top -= e.Y;
		btnno.Left += e.X;
		if (btnno.Top < -10 || btnno.Top > 100)
		btnno.Top = 60;
		if (btnno.Left < -80 || btnno.Left > 250)
		btnno.Left = 120;
}

Запустите приложение. Теперь, при выборе "Да" появляется окно с надписью, а при попытке нажать на кнопку "Нет" она "убегает" (рис. 1.41).

Готовое приложение SocOpros

Рис. 1.41. Готовое приложение SocOpros

С событиями мыши связано большинство инструментов во многих программах, а для некоторых, например, графических, — это основа всего взаимодействия с пользователем. Другие события мыши — такие как MouseDown, MouseEnter, MouseUp — могут быть использованы для получения необычной реакции на действия пользователя в этом приложении.

На диске, прилагаемом к книге, вы найдете приложение SocOpros (Code\Glava1\ SocOpros ).

Лекция 1: 12345678910 || Лекция 2 >
Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/

Анатолий Федоров
Анатолий Федоров
Россия, Москва, Московский государственный университет им. М. В. Ломоносова, 1989