Обработчик событий windows forms c

Последнее обновление: 31.10.2015

Для взаимодействия с пользователем в Windows Forms используется механизм событий. События в Windows Forms представляют стандартные события на C#, только
применяемые к визуальным компонентам и подчиняются тем же правилам, что события в C#. Но создание обработчиков событий в Windows Forms все же
имеет некоторые особенности.

Прежде всего в WinForms есть некоторый стандартный набор событий, который по большей части имеется у всех визуальных компонентов. Отдельные элементы
добавляют свои события, но принципы работы с ними будут похожие. Чтобы посмотреть все события элемента, нам надо выбрать этот элемент в
поле графического дизайнера и перейти к вкладке событий на панели форм. Например, события формы:

Чтобы добавить обработчик, можно просто два раза нажать по пустому полю рядом с названием события, и после этого Visual Studio
автоматически сгенерирует обработчик события. Например, нажмем для создания обработчика для события Load:

И в этом поле отобразится название метода обработчика события Load. По умолчанию он называется Form1_Load.

Если мы перейдем в файл кода формы Form1.cs, то увидим автосгенерированный метод Form1_Load:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }
}

И при каждой загрузке формы будет срабатывать код в обработчике Form1_Load.

Как правило, большинство обработчиков различных визуальных компонентов имеют два параметра: sender — объект, инициировавший событие,
и аргумент, хранящий информацию о событии (в данном случае EventArgs e).

Но это только обработчик. Добавление же обработчика, созданного таким образом, производится в файле Form1.Designer.cs:

namespace HelloApp
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        private void InitializeComponent()
        {
            this.SuspendLayout();

            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Name = "Form1";
			// добавление обработчика 
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
        }
    }
}

Для добавления обработчика используется стандартный синтаксис C#: this.Load += new System.EventHandler(this.Form1_Load)

Поэтому если мы захотим удалить созданный подобным образом обработчик, то нам надо не только удалить метод из кода формы в Form1.cs, но и
удалить добавление обработчика в этом файле.

Однако мы можем добавлять обработчики событий и програмно, например, в конструкторе формы:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HelloApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Load += LoadEvent;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void LoadEvent(object sender, EventArgs e)
        {
            this.BackColor = Color.Yellow;
        }
    }
}

Кроме ранее созданного обработчика Form1_Load здесь также добавлен другой обработчик загрузки формы: this.Load += LoadEvent;, который
устанавливает в качестве фона желтый цвет.

События в 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).

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

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

События мыши

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

Form1, форма, свойство Значение
FormBorderStyle Fixed3D
Icon Путь 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).

Рис.
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).

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

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

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

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

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

private void ClickOnReferences<T>(object sender, EventArgs e)
            where T: Form, new()

        {
            string name = ((ToolStripMenuItem)sender).Name;
            if (!CheckMdiChildrenInMdiContainer(name))
            {
                var form = new T();
                form.MdiParent = this;
                form.Name = name;
                form.Show();
            }
        }

Необходимо на него подписать несколько обработчиков событий по клику
Я делал так

this.Students.Click += new System.EventHandler(this.ClickOnReferences<StudentsForm>);

Если выполнить сборку, то после сохранения он станет выглядить так

this.Students.Click += new System.EventHandler(this.ClickOnReferences);

И начнет выдавать ошибку, что нужно явно определить тип аргумента
Может я что неправильно делаю? У меня следующая суть задания, нужно при клике на определенный ToolStripMenuItem открывать определенную форму, сначала делал для каждого itemа свой обработчик и все работало, но решил сделать обобщенный и наткнулся на такую особенность. Так же, если вместо сборки запустить приложение, то все будет работать нормально, но дальше ситуацию повторяется

В платформе .NET, как и в Win32, для информирования о возникновении какого-либо состояния или о действии используются события, или иногда их еще называют сообщения (по-английски: events). Например, в ответ на изменение положения окна оно генерирует событие определенного класса, которое мы можем перехватить.

Для того чтобы перехватить событие, нужно создать его обработчик. Обработчик события по сути является методом, который регистрируется на отлов определенного события от определенного элемента управления/формы/компонента. Когда
наступит событие, то этот самый элемент управления/форма/компонент вызовет метод, в котором мы можем написать код реакции на событие.

С помощью визуального дизайнера Visual Studio создание обработчиков событий превращается в тривиальную задачу. На рис. 5.8 показана панель Properties в режиме просмотра событий. Чтобы увидеть что-то подобное, нужно выделить компонент, событие которого вы хотите поймать, и нажать кнопку Events в панели Properties (на рис. 5.8 эта кнопка обведена кружком). Чтобы вернуться обратно к просмотру свойств, надо щелкнуть по кнопке Properties, которая находится левее.

Рис. 5.8. Панель Properties
при просмотре событий

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

Давайте создадим обработчик события MouseClick. Выделите форму, перейдите
в панели Properties в режим просмотра событий Events и щелкните двойным щелчком напротив события. Будет создан метод Form1_MouseClick():

   private void Form1_MouseClick(object sender, MouseEventArgs e)
   {
     MessageBox.Show("Клик");
   }

Я здесь добавил внутрь метода обработки события вызов статического метода Show() класса MessageBox. Этот метод отображает на рабочем столе диалоговое окно с сообщением, которое вы передали в качестве параметра. В нашем случае каждый раз, когда вы щелкнете по форме, будет появляться сообщение: Клик.

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

  • Load — загрузка;
  • Activate — активация;
  • VisibleChanged — изменилось свойство Visible.
  • А при закрытии формы генерируются следующие события:
  • Deactivated — деактивировано;
  • Closing — закрытие формы (можно отменить закрытие);
  • Close — форма закрыта, и назад дороги нет.

Событие Load генерируется, когда вы впервые вызываете метод Show() для отображения формы. Посмотрим на следующий пример:

   MyForm form = new MyForm();
   form.Show();   // отобразить форму
   form.Hide();   // спрятать с помощью Hide()
   form.Show();   // Отобразить снова

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

Очень часто у вас будут возникать казусы со случайным созданием событий. Например, если щелкнуть двойным щелчком по компоненту в визуальном дизайнере, то будет создан обработчик события по умолчанию для этого компонента. Так, для кнопки событием по умолчанию является Click, и если вы случайно щелкнете двойным щелчком по компоненту в визуальном дизайнере, то будет создан такой обработчик события. А если вы не хотели его создавать? Оставлять заготовку
метода в коде? Наверное, лучше, все же, убрать обработчик события, чтобы он не мешал. Как это сделать?

Существует несколько вариантов:

  • Выделите компонент в визуальном дизайнере и перейдите в режим Events в панели свойств. Напротив события удалите в поле название метода, созданного для обработчика события. Визуальный редактор удалит регистрацию события, которую он автоматически добавил в свой метод InitializeComponent(). Если
    в обработчике события не было кода, то заготовка для метода исчезнет и из кода.
  • Если обработчик события содержит код, но он уже не нужен, то можно сначала удалить код из обработчика события, а потом выполнить действия из предыдущего пункта.
  • Если обработчик события содержит код, то можно сначала удалить имя обработчика события в режиме Events панели свойств, а потом безболезненно удалить код метода.

Если вы создали обработчик события и тут же удалили метод в редакторе кода,
то при этом среда разработки не удалит регистрацию события в методе InitializeComponent(). Это придется делать вручную. Как это сделать безболезненно? Давайте посмотрим на примере.

Создайте новое приложение и поместите на его форму кнопку. Щелкните по кнопке двойным щелчком, и среда разработки переключит вас в редактор кода с созданным для обработки события методом:

private void button1_Click(object sender, EventArgs e)
{
}

Удалите эту заготовку кода из редактора и попробуйте скомпилировать проект. Внизу окна появится сообщение об ошибке (рис. 5.9). В этой ошибке компилятор сообщает нам, что обработчик события не найден. Щелкните двойным щелчком по ошибке, и откроется вкладка с файлом (Form1.Designer.cs), где найдена ошибка, и

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

 Сообщение об ошибке, что обработчик события не найден

Рис. 5.9. Сообщение об ошибке, что обработчик события не найден

Это бесплатная глава книги Библия C#. В новом издании эта глава переписана с учетом универсальных при-ложений Windows, а старая версия главы, которая не потеряла еще своей актуаль-ности стала бесплатной и доступной всем.

Все исходные коды главы 5 Библии C#

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Windows xp philka sp2
  • Dns w170er драйвера windows 7 x64
  • Windows 10 uninstall driver
  • Сколько озу потребляет windows xp
  • Устранить ошибки возникающие при работе с библиотекой в ос windows можно с помощью