为多个事件侦听器调用反射方法C#

时间:2017-12-15 20:28:54

标签: c# for-loop reflection event-handling panel

我有一个窗口表单,其中包含几个面板Panel[,]。每次用户点击任何面板时,我都希望处理单击面板的特定且唯一的事件。我想过有一个带有switch语句的单个事件,但我认为它的实践相对相同,并且使用起来会更加混乱。也许我对事件处理程序的设计都错了..

我尝试做的事情看起来与此相似:

Type t = typeof(Program);
var methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name.EndsWith("_click")).ToArray();
char[] cArr = { 'a', 'b', 'c', 'd' };

for(int i = 0; i < 4; i++)
{
    for(int j = 0; j < 4; j++)
    {
        MethodInfo method = methods.Single(
             m => m.Name == cArr[i].ToString() + (j + 1) + "_click");
        //  method.Invoke(null, null);
        //  myPanels[i, j].Click += new EventHandler( );
    }
}

private void a1_click(object sender, System.EventArgs e)
{
    MessageBox.Show("Unique event A1");
}
private void a2_click(object sender, System.EventArgs e)
{
    MessageBox.Show("Unique event A2");
}
//...
private void d4_click(object sender, System.EventArgs e)
{
    MessageBox.Show("Unique event D4");
}

如果您知道通过设计方法更好地处理事件,请告诉我,因为我很乐意理解这一点。但是就这个例子而言,我应该如何将该方法放在EventHandler中。如果我手动分配它们,我可以做这样的事情:

myPanels[0, 0].Click += new EventHandler(a1_click);

但我宁愿遍历任务部分,也不要重新考虑事件本身。

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

也许更好的方法是使用参数而不是不同的事件处理程序。

以下示例使用Tag属性来区分发送事件的面板,尽管您应该通过创建事件参数并发送而不是null来实际使用EventArgs。

void Main()
{
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            myPanels[i, j].Tag = i +" - " + j;
            myPanels[i, j].Click += button_click;
            // fire the event, note that the panel instance is the sender
            myPanels[i, j].OnClick(null);
        }
    }
}

private void button_click(object sender, System.EventArgs e)
{
    var pnl = sender as Panel;
    if (pnl != null && pnl.Tag != null)
        MessageBox.Show("Unique event "+ pnl.Tag.ToString());
}

如果您希望每个面板都实现特殊行为,您可以创建一个Panel的子类并实现一个接口;

public interface ISpecialMethod{
    void SpecialMethod();
}

public class SpecialPanel :Panel, ISpecialMethod {
    public void SpecialMethod() {
        /* custom logic*/
    }
}

private void button_click(object sender, System.EventArgs e)
{
    var pnl = sender as ISpecialMethod ;
    if (pnl != null)
        pnl.SpecialMethod();
}

从这里开始,可能性无穷无尽。

答案 1 :(得分:1)

这种情况不太可能是您的实际情况,但如果您真的想要动态地连接事件,则只需要对现有代码进行少量添加:

myPanels[i, j].Click += (EventHandler) method.CreateDelegate(typeof(EventHandler));