代码之家  ›  专栏  ›  技术社区  ›  ctacke

处理窗体上所有控件的单击

  •  9
  • ctacke  · 技术社区  · 16 年前

    我有一个.NET用户控件(ffx 3.5)。此控件包含多个子控件-一个面板、多个标签、多个文本框,还有另一个自定义控件。我想在基本控件的任意位置处理右键单击,所以右键单击任何子控件(或者面板中的子控件)。我想这样做,如果有人在不需要连接新控件的处理程序的情况下对控件进行更改,那么它是可维护的。

    首先,我尝试覆盖wndproc,但正如我所怀疑的,我只收到直接点击表单的消息,而不是它的任何子表单。作为半黑客,我在初始化组件后添加了以下内容:

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

    现在可以单击支持事件的控件,但标签(例如)仍然无法获得任何内容。有没有一个简单的方法可以做到这一点,我忽略了?

    2 回复  |  直到 9 年前
        1
  •  17
  •   Mark Cidade    10 年前

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

    void initControlsRecursive(ControlCollection coll)
     { 
        foreach (Control c in coll)  
         {  
           c.MouseClick += (sender, e) => {/* handle the click here  */});  
           initControlsRecursive(c.Controls);
         }
     }
    
    /* ... */
    initControlsRecursive(Form.Controls);
    
        2
  •  0
  •   Szabolcs Antal    9 年前

    处理 莫斯克利克 事件,右键单击自定义控件上的所有控件 用户控制 :

    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.");
        }
    }