使用事件处理程序处理多个对象

5
我有一个包含20个List<myObject>的列表。每个对象都有一个关联的UserControl实例。每个对象都可以通过一个MenuStrip访问,需要在相应的菜单项被单击时显示UserControl。目前,我为每个对象都有一个事件处理程序,虽然这样做是有效的,但我想知道是否存在一种方法,可以简化它并使用一个事件处理程序来处理所有的项目。
这是否可行?如果是,最好的方法是什么?
编辑:还有其他人能提供有关此问题的任何输入吗?我对Mailo的回答感到困惑。本质上,我所需要做的就是编写一个事件处理程序,并在单击正确的MenuStrip项目时将存储在List<myObject>中的适当的属性显示出来。是否有更直接的方法来完成这项任务?理想情况下,我希望能够使foreach循环遍历列表并设置处理程序。
有没有人能帮助我解决这个问题?

单独的处理程序基本上是相同的吗?您可以拥有一个并识别即将到来的内容,然后简单地以不同的方式做出反应,例如根据您所知道的进行切换吗?也许利用UserControl.Tag属性? - DonBoitnott
每个处理程序基本上都是做同样的事情。它只显示相应的用户控件。 - Jason D
我也尝试使用标签属性,但仍然没有成功。 - Jason D
3个回答

3
这并不是非常困难。首先,你需要一种方法将菜单项与列表中的控件关联起来。 1)因为你有一个列表,使用索引是最简单的方法(你可以使用Dictionary<>来简化此关联)。所以,假设当你点击第一个菜单项时,你希望 myObjectList[0]出现。当你点击第二个菜单项时,myObjectList[1]就会出现,以此类推。为此,请进入每个菜单项,在属性中给Tag属性赋值。对于第一个菜单项,将Tag分配为0,对于第二个菜单项,将Tag分配为1-依此类推。 2)创建一个事件处理程序,并将同一个处理程序分配给所有菜单项。事件处理程序可能如下所示:
private void myToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // source menu item which was clicked
            ToolStripMenuItem item = sender as ToolStripMenuItem;

            if(item != null) 
            {
                int index = int.Parse(item.Tag.ToString()); // get the index from Tag
                myObject control = myObjectList[index];

                // do your stuff with your control

            }
        } 

0

你可以将发送者对象传递给事件处理程序,并在处理程序内部检查类型。

大致代码如下:

    //this will contain any properties you wanna send to the handler 
public class MyHandlerEventArgs : EventArgs
{

}

//this delegate gets the sender, you can change the sender type to be the encapsulated type of your controls
public delegate void MyHandler(object sender, MyHandlerEventArgs args);

//this is the class that fires the event in your case it will UI class I think
public class  MyController
{
    public event MyHandler myEvent;

    public void MyEvent_Fire()
    {
        if(myEvent != null)
            myEvent(this, new MyHandlerEventArgs());
    }
}

//here you can do your business logic for each control
public class MyAction
{
    MyController mc = new MyController();
    public MyAction()
    {
        mc.myEvent += new MyHandler(mc_myEvent);
    }

    void mc_myEvent(object sender, MyHandlerEventArgs args)
    {
        //check the sender type 
        //do your action
    }
}

这个链接可能对检查有用。


3
为什么不使用EventHandler<T>,而是定义一个与默认委托基本相同签名的自定义委托? - Marcel N.
@marceln,我错过了这个,EventHandler<T>会是一个更好的想法。感谢您的评论。 - Mailo

0

您可能需要来自MenuStripItemClicked事件。 您可以使用ToolStripItemClickedEventArgs中的ClickedItem找到您的UserControl

一些伪代码:

// Initialize
myMenuStrip.ItemClicked += itemClickedEvent;

// ...
void itemClickedEvent(Object sender, ToolStripItemClickedEventArgs e)
{
  int index = myObjectList.FindIndex(e => e.instanceOfUserControl == e.ClickedItem);
  // Now that we have the clicked item, display it how we would in an individual event handler.
  myObjectList[index].instanceOfUserControl.DoDisplay();
}

理想情况下,我希望能够使用 foreach 循环遍历列表并设置处理程序。
在这种方法中,您将使用 foreach 语句对 List 进行操作。
foreach (var listItem in myObjectList)
{
  listItem.TheEvent += myEventHandler;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接