? С# для Windows

Определение контрола, вызвавшего событие

Необходимость определять контрол, вызвавший то или иное событие, возникает тогда, когда различные или одинаковые события различных контрол замыкаются на один обработчик, в котором действия обработчика специфичны в зависимости от контрола, вызвавшего событие.

Создадим Windows Application решение как показано в параграфе "Простейшие Windows Application решения" и поместим на форму два контрола Button. Создадим один обработчик события нажатия кнопки для контрола button1 (напомним, это можно сделать двойным кликом на кнопке в дизайнере формы), а обработчик события нажатия кнопки для button2 переопределим на обработчик для button1. Для этого выберем мышкой контрол button2 и в окне Proporties перейдем к вкладке Events, далее для события Сlick в выпадающем списке выберем button1_Click. Как результат при нажатии кнопки 1 и 2 будет вызываться один и тот же обработчик button1_Click.

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

private void button1_Click(object sender, EventArgs e)
{
 MessageBox.Show(this,(sender as Button).Text,"Какая кнопка");  
}

Запустив приложение, видим, что текст вывода соответствует надписи на кнопке.

Другой способ определить номер кнопки через статическое преобразование типов - это дополнительно присвоить свойствам Tag кнопок разные номера (например button1 Tag=1, button2 Tag=2);

Перепишем код обработчика следующим образом:

private void button1_Click(object sender, EventArgs e)
{
 int k=Convert.ToInt32((sender as Button).Tag);
 string s="Вы нажали кнопку ";
 switch (k)
 {
  case 1:
   s+="номер 1";
  break;					
  case 2:
   s+="номер 2";			
  break;
  default:
   s="Да не могли Вы сюда попасть";
  break;
 }
 MessageBox.Show(this,s,"Какая кнопка?"); 
}

Опять четко определяется нажатая кнопка.

Этот обработчик можно назначить сразу нескольким контролам, но только TButton. При попытке преобразования к другого типу контрола, программа выдаст исключение на преобразование типов. Если же необходимо выполнить преобразование из неизвестного класса, то можно использовать конструкции try...catch.


В начало

Определение через массив Controls

Все визуальные контролы на форме хранятся в массиве Controls. При переносе контрола на форму ему автоматически присваивается номер 0 в массиве, а остальные номера контрол увеличиваются на 1. Число контрол на форме хранится в свойстве Count. Используя это, следующий код ищет среди всех контрол формы контролы Button и если найден такой контрол выводит его имя.

for(int i=0; i < this.Controls.Count; i++)
{
 //Ищем контролы Button 
 if(Convert.ToString(this.Controls[i].GetType().Name) == "Button")
 {
  MessageBox.Show(this,
    Convert.ToString(this.Controls[i].Name),
	"Какие есть кнопки?"); 
 }	
}

Условия поиска можно расширить на область всех кнопок (не зависимо от их типа):

if(Convert.ToString(this.Controls[i].GetType().BaseType) 
                         == "System.Windows.Forms.ButtonBase")

Уточнение конкретного элемента, как и в примере первого параграфа, можно вести по свойству Tag.

Поместим на форму, которая была испольозована в предыдущем параграфе, еще несколько контролов (например Button, RadioButton, CheckBox) и переопределим их события Click на button1_Click, код обработки которого перепищим на следующий:

private void button1_Click(object sender, EventArgs e)
{
 string s;
 int a,b;
 for(int i=0; i < this.Controls.Count; i++)
 {
  //Tag контрола
  a=Convert.ToInt32(this.Controls[i].Tag);
  if(Convert.ToString(this.Controls[i].GetType().BaseType) 
                       == "System.Windows.Forms.ButtonBase")
  {
   //Tag источника события
   b=Convert.ToInt32((sender as Button).Tag);	
   //Tag контрола в массиве совпал с Tag источника события
   if(a == b)
   {
    switch (b)
    {
     case 1:
      s="Вы нажали кнопку номер 1";
     break;					
     case 2:
      s="Вы нажали кнопку номер 2";			
     break;
     default:
      s="Да не могли Вы сюда попасть";
     break;
    }
   }//if(a == b)
   MessageBox.Show(this,s,"Какая кнопка?"); 
  }//if(Convert.ToString(this.Controls[i]...
 }//for(int i=0; i < this.Controls.Count; i++)
}

В примере опять безошибочно определяется какая из двух кнопок нажата.

Отметим, что конструкции this.Controls[i]. доступны все свойства и методы контрола (если они определены). Такой доступ часто используется, и, в принципе, без этого и не обойтись, когда на форме много одинаковых контролов, а код обработчика каких либо событий одинаков или схож. К примеру если на форме 100 контролов ImageBox и надо изменить свойство (например Visible) одного из них по клику на нем мышки, то не писать же один и тот же код в 100 обработчиках.

Если на форме кроме Button-а, еще и другие контролы можно ставить такие как: RadioButton, CheckBox, то их можно использовать с одним обработчиком button1_Click, используя следующий код (прислал Фируз Икром).

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string s;
            int a, b;
            for (int i = 0; i < this.Controls.Count; i++)
            {
                //Tag контрола
                a = Convert.ToInt32(this.Controls[i].Tag);
                if (Convert.ToString(this.Controls[i].GetType().BaseType)
                    == "System.Windows.Forms.ButtonBase")
                { 
                    //Tag источник события
                    b = Convert.ToInt32((sender as ButtonBase).Tag);
                    //Tag контрола в массиве совпал с Tag источника события
                    if (a == b)
                    {
                        switch (b)
                        { 
                            case 1:
                                s = "Вы нажали кнопку номер 1"; break;
                            case 2:
                                s = "Вы нажали кнопку номер 2"; break;
                            case 3:
                                s = "Вы нажали" + " " +
                                    Convert.ToString(this.Controls[i].GetType().Name)
                                  + " " + "номер 3"; break;
                            case 4:
                                s = "Вы нажали" + " " +
                                    Convert.ToString(this.Controls[i].GetType().Name)
                                  + " " + "номер 4"; break;
                            default:
                                s = "Да не мог ты сюда попасть"; break;
                        } MessageBox.Show(this, s, "Какая кнопка?");
                    }// if(a == b)
                    
                }// if(Convert.ToString(this.Controls[i] ...
            }// for (int i = 0; i < this.Controls.Count; i++)
        }
    } 
}

Молчанов Владислав 25.06.2004г.

Проверена работоспособность в VS 2005 5.11.2006г.

Еcли Вы пришли с поискового сервера - посетите мою главную страничку

На главной странице Вы найдете программы комплекса Veles - программы для автолюбителей, программу NumberPhoto, созданную для работы с фото, сделанными цифровым фотоаппаратом, программу Bricks - игрушку для детей и взрослых, программу записную книжку, теоретический материал по программированию в среде Borland C++ builder, C# (C .Net).

На главную страницу

В начало страницы

К началу раздела


Сайт управляется системой uCoz