2010-06-01 2 views
3

У меня есть панель, содержащая 20 элементов управления PictureBox. Если пользователь нажимает на любой из элементов управления, я хочу, чтобы вызываемый метод вызывал панель.Способ регистрации метода, который будет вызываться при возникновении события

Как это сделать?

public class MyPanel : Panel 
{ 
    public MyPanel() 
    { 
     for(int i = 0; i < 20; i++) 
     { 
     Controls.Add(new PictureBox()); 
     } 
    } 

    // DOESN'T WORK. 
    // function to register functions to be called if the pictureboxes are clicked. 
    public void RegisterFunction(<function pointer> func) 
    { 
     foreach (Control c in Controls) 
     { 
      c.Click += new EventHandler(func); 
     } 
    } 
} 

Как осуществить RegisterFunction()? Кроме того, если есть классные функции C#, которые могут сделать код более элегантным, пожалуйста, поделитесь.

+0

Вы хотите, чтобы функция выполнялась только в том случае, если они нажимают на элемент управления на панели управления внутри панели? – msarchet

ответ

7

«Функциональный указатель» представлен типом делегата в C#. Событие Click ожидает делегата типа EventHandler. Таким образом, вы можете просто передать EventHandler методу RegisterFunction и зарегистрировать его для каждого Click события:

public void RegisterFunction(EventHandler func) 
{ 
    foreach (Control c in Controls) 
    { 
     c.Click += func; 
    } 
} 

Использование:

public MyPanel() 
{ 
    for (int i = 0; i < 20; i++) 
    { 
     Controls.Add(new PictureBox()); 
    } 

    RegisterFunction(MyHandler); 
} 

Обратите внимание, что это добавляет элемент управления EventHandler делегат в каждый, а не только элементы управления PictureBox (если есть другие). Лучший способ, вероятно, добавить обработчики событий времени при создании элементов управления PictureBox:

public MyPanel() 
{ 
    for (int i = 0; i < 20; i++) 
    { 
     PictureBox p = new PictureBox(); 
     p.Click += MyHandler; 
     Controls.Add(p); 
    } 
} 

метод, который EventHandler делегат указывает, выглядит следующим образом:

private void MyHandler(object sender, EventArgs e) 
{ 
    // this is called when one of the PictureBox controls is clicked 
} 
0

Как DTB упоминалось вы определенно следует назначить EventHandler при создании каждого PictureBox. Кроме того, вы можете использовать выражение лямбда для этого.

public MyPanel() 
{ 
    for (int i = 0; i < 20; i++) 
    { 
     PictureBox p = new PictureBox(); 
     var pictureBoxIndex = i; 
     p.Click += (s,e) => 
     { 
      //Your code here can reference pictureBoxIndex if needed. 
     }; 
     Controls.Add(p); 
    } 
} 
+2

Имейте в виду, что выражение лямбда захватывает переменную 'i', а не значение переменной' i'. – dtb

+0

@dtb Да, я обновил, чтобы показать, как получить значение вместо этого. – juharr

Смежные вопросы