How do I set a click event for a form?

前端 未结 6 725
名媛妹妹
名媛妹妹 2021-01-05 10:37

I have a c# form (let\'s call it MainForm) with a number of custom controls on it. I\'d like to have the MainForm.OnClick() method fire anytime someone clicks on the form re

相关标签:
6条回答
  • 2021-01-05 10:51

    This is a common pattern in development, its called the Observer pattern. There are lots of examples of Observer patterns and c# here is 1 example http://msdn.microsoft.com/en-us/library/ms954621.aspx but have a good google around.

    0 讨论(0)
  • 2021-01-05 10:58

    I recommend creating a base form for the other forms in your application to inherit. Add this code to your base form to create a new event called GlobalMouseClickEventHandler:

    namespace Temp
    {
        public delegate void GlobalMouseClickEventHander(object sender, MouseEventArgs e);
    
        public partial class TestForm : Form
        {
            [Category("Action")]
            [Description("Fires when any control on the form is clicked.")]
            public event GlobalMouseClickEventHander GlobalMouseClick;
    
            public TestForm()
            {
                InitializeComponent();
                BindControlMouseClicks(this);
            }
    
            private void BindControlMouseClicks(Control con)
            {
                con.MouseClick += delegate(object sender, MouseEventArgs e)
                {
                    TriggerMouseClicked(sender, e);
                };
                // bind to controls already added
                foreach (Control i in con.Controls)
                {
                    BindControlMouseClicks(i);
                }
                // bind to controls added in the future
                con.ControlAdded += delegate(object sender, ControlEventArgs e)
                {
                    BindControlMouseClicks(e.Control);
                };            
            }
    
            private void TriggerMouseClicked(object sender, MouseEventArgs e)
            {
                if (GlobalMouseClick != null)
                {
                    GlobalMouseClick(sender, e);
                }
            }
        }
    }
    

    This solution will work not only for top-level controls, but also nested controls such as controls placed inside of panels.

    0 讨论(0)
  • 2021-01-05 11:04

    You can hook all the control's events, if you like, and then monitor that way. I assume there is some uber fancy Win32 api way to trap them all, but that is beyond me at the moment.

        public Form1()
        {
            InitializeComponent();
            HookEvents();
        }
    
        private void HookEvents() {
            foreach (Control ctl in this.Controls) {
                ctl.MouseClick += new MouseEventHandler(Form1_MouseClick);
            }
        }  
    
        void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            LogEvent(sender, "MouseClick");
        }
    
        // and then this just logs to a multiline textbox you have somwhere on the form
        private void LogEvent(object sender, string msg) {
            this.textBox1.Text = string.Format("{0} {1} ({2}) \n {3}",
                DateTime.Now.TimeOfDay.ToString(),
                msg,
                sender.GetType().Name,
                textBox1.Text
                );
        }
    

    The output is something like this, showing all the events and who "sent" them up:

    14:51:42.3381985 MouseClick (Form1) 
    14:51:40.6194485 MouseClick (RichTextBox) 
    14:51:40.0100735 MouseClick (TextBox) 
    14:51:39.6194485 MouseClick (Form1) 
    14:51:39.2131985 MouseClick (RichTextBox) 
    14:51:38.8694485 MouseClick (Button) 
    

    HTH.

    0 讨论(0)
  • 2021-01-05 11:09

    Catching a click on an open space on the form is easy, but to get a click that's actually on a control, you'll need the cooperation of that control to send it to the form.

    One possibility is to place a transparent control over the entire form, and accept clicks onto that, deal with them, and then pass them onto the proper control underneath.

    0 讨论(0)
  • 2021-01-05 11:13

    In the form's ControlAdded event, add a MouseClick handler to the control, with the Address of the form's click event. I haven't tested this, but it might work.

    Private Sub Example_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles Me.ControlAdded
    
        AddHandler e.Control.MouseClick, AddressOf Example_MouseClick
    End Sub
    
    Private Sub Example_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
        MessageBox.Show("Click")
    End Sub
    
    0 讨论(0)
  • 2021-01-05 11:13

    The only way I've ever managed to do this is to handle the [c]Click[/c] event of every control. I don't believe the event is raised before the control processes it.

    In WPF, there are "tunneling" preview events that provide this functionality, but that doesn't really help you in WinForms.

    0 讨论(0)
提交回复
热议问题