Обработчик события для динамического контрола из массива

Brud

Добрый день, имеется множество Button, которое создаётся на форме динамически:
ALLOFF[k / pagesize] = gcnew Button();
TB[k / pagesize]->Controls->Add(ALLOFF[k / pagesize]);
ALLOFF[k / pagesize]->Name = L"ALLOFF" + k / pagesize;
ALLOFF[k / pagesize]->Location = System::Drawing::Point(124, 16);
ALLOFF[k / pagesize]->Size = System::Drawing::Size(13, 13);
Как можно туда добавить обработчик события "Click"?p/s Пробовал сделать это так:
ALLOFF[k / pagesize]->Click += gcnew System::EventHandler(this, &MyForm::ALLOFF[k / pagesize]_Click);
 
private: System::Void ALLOFF[k / pagesize]_Click(System::Object^  sender, System::EventArgs^  e)
14 ответов

Brud

ALLOFF[k / pagesize]->Click += gcnew System::EventHandler(this, &MyForm::ALLOFF[k / pagesize]_Click
Это как? У вас как метод обработчика называется?


Brud

Я всё сделал по пободию кода, который Visual Studio автоматически создаёт для событий, Нужно, чтобы для каждой кнопки[i] создавался свой обработчик[i].


Brud

Так в обработчике код то какой? Он что из воздуха берется? такого быть не может.
ТИП НАИМЕНОВАНИЕ_МЕТОДА([ПАРАМЕТРЫ])
{
[КОД]
}
Вот на что должен ссылать делегат, на наименование реально написанного методаЕсли вы имеете ввиду генерацию кода методов в дизайнере VS, то изучайте макросы


Brud

Ссылается он на это:
private: System::Void ALLOFF[k / pagesize]_Click(System::Object^  sender, System::EventArgs^  e)
{
Код
}
Но ошибки возникают уже на этапе того, что ему не нравится эта часть: ALLOFF[k / pagesize]->Click += gcnew System::EventHandler(this, &MyForm::ALLOFF[k / pagesize]_Click);Как я понял, для динамических контролов нужно обработчик добавлять по-другому


Brud

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


Brud

Понял, спасибо, тогда другой вопрос, можно ли добавить к списку параметров по умолчанию (this, &MyForm::ALLOFF_Click) ещё один?И второй вопрос - как в обработчике получить доступ к создаваемым дин. элементам? Т.е. у меня есть Форма, на неё добавлен TabControl, всё остальное - TabPage->Button добавляется динамически и я не могу обратиться к Button[0], т.к. её как бы и не существует


Brud

Понял, спасибо, тогда другой вопрос, можно ли добавить к списку параметров по умолчанию (this, &MyForm::ALLOFF_Click) ещё один?
Не понял. Еще один обработчик? Можно. Точно также, следующе строкой, указав ссылку на другой метод
И второй вопрос - как в обработчике получить доступ к создаваемым дин. элементам?
private: System::Void ALLOFF_Click(System::Object^  sender, System::EventArgs^  e)
{
Button ^bt = (Button^)sender;
//идентифицировать можно по Name
//if(bt->name=="ButtonName")
//{
//КОД
//}
//а лучше при инициализации кнопок в Tag записать число - идентификатор кнопки и по нему ориентироваться
}


Brud

Спасибо, но как получить Tag той кнопки, которая вызывает обработчик и как обратиться к конкретному элементу по Tag?Обращение к элементам по имени невозможно, т.к. количество элементов неизвестно и меняется в зависимости от входных данных, поэтому нужна работа напрямую с индексами массива (или Tag).И ещё проблема в том, что элементы раположены не напрямую на форме, а примерно так: Form->TabControl->TabPage[i]->GroupBox[j]-RadioButton[j]. Для Button примерно тоже самое.


Brud

Из первого поста
ALLOFF[k / pagesize] = gcnew Button();
TB[k / pagesize]->Controls->Add(ALLOFF[k / pagesize]);
ALLOFF[k / pagesize]->Name = L"ALLOFF" + k / pagesize;
ALLOFF[k / pagesize]->Location = System::Drawing::Point(124, 16);
ALLOFF[k / pagesize]->Size = System::Drawing::Size(13, 13);
 
ALLOFF[k / pagesize]->Tag = int(k / pagesize);
В обработчике
Button ^bt = (Button^)Sender;
int index = (int)bt->Tag;
Для оптимизации обращения к элементу в массиве лучше сделать так
int index = int(k / pagesize); //а лучше просто i
ALLOFF[index] = gcnew Button();
TB[index]->Controls->Add(ALLOFF[index]);
//и т.д.


Brud

С получением индекса кнопки, из которой происходит вызов понял Но всё же не понял, как обратиться к RadioButton, если она находится здесь: Form->TabControl->TabPage[k / pagesize]->GroupBox[k]-RadioButton[k]А Button, на который нужно нажать: Form->TabControl->TabPage[k / pagesize]->Button[k / pagesize]Т.е. мне нужно подняться на уровень ниже и потом спуститься?
int index = int(k / pagesize); //а лучше просто i
ALLOFF[index] = gcnew Button();
TB[index]->Controls->Add(ALLOFF[index]);
//и т.д.
И чем это отличается от того, что у меня? k / pagesize используется для постраничного добавления кнопок, где k - индекс кнопки в массиве, а pagesize - параметр по достижению которого будет создаваться новая TabPage.


Brud

Form->TabControl->TabPage[k / pagesize]->GroupBox[k]-RadioButton[k]
Так вы не обратитесь, тем более такой не может быть структуры У вас есть массив ALLOFF. Он выведет в тело класса или только в методе существует? Вот если он выведен в тело класса, то можно по индексу обратиться к любому элементу.
И чем это отличается от того, что у меня?
Тем что вычисление индекса производится только один раз и код обращения становится лаконичен слегка. Чем меньше вычислений, тем меньше нагрузка на проц


Brud

Сам массив radioButton объявлен здесь:
public ref class MainForm : public System::Windows::Forms::Form
{
  ...
  array<RadioButton^>^RBOFF = gcnew array<RadioButton^>(i + 1);
  ...
}
А создание и выделение памяти под каждый элемент здесь:
void InitializeComponent(void)
{
  ...
  RBOFF[k] = gcnew RadioButton();
  GP[k]->Controls->Add(RBOFF[k]);
  RBOFF[k]->Location = System::Drawing::Point(13, 13);
  RBOFF[k]->Name = L"RBOFF" + k.ToString();
  RBOFF[k]->Size = System::Drawing::Size(14, 13);
  RBOFF[k]->Checked = 1;
  ...
}


Brud

Ну точно так же как с кнопкой.
RBOFF[k]->Tag = k;
+обработчик клика (или CheckedChanged)И в обработчике
RadioButton ^rb = (RadioButton^)sender;
int index = (int)rb->Tag;
//...
В .net в основном принято, если это не статический контрол вызывает событие, то он отправляет свое тело через переменную вызываемую в обработчик - sender


Brud

Так мне же нужно сделать обработку нажатия на самой radioButton, мне нужно, чтобы по нажатию одной Button выделялись rBtn на текущей странице, а при нажатии другой Btn, в зависимости от того, Checked ли rBtn или нет, выполнялись уже определённые действия. Если нужно, могу приложить скриншот окна программы, чтобы показать, как это выглядит