处理表单上的所有控件的单击

时间:2008-10-29 18:45:45

标签: c# winforms events

我有一个.NET UserControl(FFX 3.5)。此控件包含几个子控件 - 一个Panel,一对标签,一对TextBox,以及另一个自定义控件。我想在基本Control上的任何地方处理右键单击 - 所以右键单击任何子控件(如果是Panel,则为子项的子项)。我想这样做,以便在有人对Control进行更改时可以维护,而不必为新控件连接处理程序。

首先我尝试覆盖WndProc,但正如我所怀疑的那样,我只会直接获取表单上的点击消息,而不是任何子节点。作为半黑客,我在InitializeComponent之后添加了以下内容:

  foreach (Control c in this.Controls)
  {
    c.MouseClick += new MouseEventHandler(
      delegate(object sender, MouseEventArgs e)
      {
        // handle the click here
      });
  }

现在,这会获得支持该事件的控件的点击次数,但是,例如,标签仍然没有得到任何结果。有一种简单的方法可以做到这一点,我忽略了吗?

2 个答案:

答案 0 :(得分:17)

如果标签在子控件中,那么你必须递归地执行此操作:

void initControlsRecursive(ControlCollection coll)
 { 
    foreach (Control c in coll)  
     {  
       c.MouseClick += (sender, e) => {/* handle the click here  */});  
       initControlsRecursive(c.Controls);
     }
 }

/* ... */
initControlsRecursive(Form.Controls);

答案 1 :(得分:0)

要处理 MouseClick 事件,右键单击自定义 UserControl 上的所有控件:

public class MyClass : UserControl
{
    public MyClass()
    {
        InitializeComponent();

        MouseClick += ControlOnMouseClick;
        if (HasChildren)
            AddOnMouseClickHandlerRecursive(Controls);
    }

    private void AddOnMouseClickHandlerRecursive(IEnumerable controls)
    {
        foreach (Control control in controls)
        {
            control.MouseClick += ControlOnMouseClick;

            if (control.HasChildren)
                AddOnMouseClickHandlerRecursive(control.Controls);
        }
    }

    private void ControlOnMouseClick(object sender, MouseEventArgs args)
    {
        if (args.Button != MouseButtons.Right)
            return;

        var contextMenu = new ContextMenu(new[] { new MenuItem("Copy", OnCopyClick) });
        contextMenu.Show((Control)sender, new Point(args.X, args.Y));
    }

    private void OnCopyClick(object sender, EventArgs eventArgs)
    {
        MessageBox.Show("Copy menu item was clicked.");
    }
}