【问题标题】:How do I set a click event for a form?如何为表单设置点击事件?
【发布时间】:2008-10-07 21:12:52
【问题描述】:

我有一个 c# 表单(我们称之为 MainForm),上面有许多自定义控件。我希望在有人单击表单时触发 MainForm.OnClick() 方法,无论单击是发生在表单上还是单击是在自定义控件之一上。我正在寻找类似于表单的 KeyPreview 功能的行为,除了鼠标点击而不是按键。

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    我建议为应用程序中的其他表单创建一个基本表单以进行继承。将此代码添加到您的基本表单以创建一个名为 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);
                }
            }
        }
    }
    

    此解决方案不仅适用于顶级控件,还适用于嵌套控件,例如放置在面板内的控件。

    【讨论】:

    • 非常感谢!一个简单而优雅的解决方案。想知道为什么没有相当于KeyPreview 的鼠标点击
    【解决方案2】:

    在窗体的 ControlAdded 事件中,将 MouseClick 处理程序添加到控件,并带有窗体单击事件的地址。我没有对此进行测试,但它可能会起作用。

    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
    

    【讨论】:

    • 这似乎仍然是一个小技巧,但这似乎是我拥有的最佳选择。
    【解决方案3】:

    我曾经设法做到这一点的唯一方法是处理每个控件的 [c]Click[/c] 事件。我不相信在控件处理之前引发事件。

    在 WPF 中,有提供此功能的“隧道”预览事件,但在 WinForms 中并不能真正帮助您。

    【讨论】:

    • 好吧,现在切换到 WPF 为时已晚,但我想我将来必须认真考虑使用它。
    【解决方案4】:

    如果愿意,您可以挂钩所有控件的事件,然后以这种方式进行监视。我认为有一些超级花哨的 Win32 api 方法可以将它们全部捕获,但目前这超出了我的范围。

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

    输出是这样的,显示所有事件以及谁“发送”了它们:

    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。

    【讨论】:

      【解决方案5】:

      在表单上的空白处捕捉点击很容易,但要获得实际在控件上的点击,您需要该控件的配合才能将其发送到表单。

      一种可能性是在整个表单上放置一个透明控件,并接受点击,处理它们,然后将它们传递给下面的适当控件。

      【讨论】:

      • 我觉得一定有比这更优雅的解决方案。
      【解决方案6】:

      这是开发中常见的模式,称为观察者模式。有很多观察者模式的例子,c# 这里有 1 个例子 http://msdn.microsoft.com/en-us/library/ms954621.aspx 但是有一个很好的 google。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多