簡體   English   中英

如何為表單設置單擊事件?

[英]How do I set a click event for a form?

我有一個ac#form(讓我們稱之為MainForm),上面有許多自定義控件。 我想在任何人點擊表單的時候觸發MainForm.OnClick()方法,無論表單上是否發生了點擊,或者點擊是否在其中一個自定義控件上。 我正在尋找類似於表單的KeyPreview功能的行為,除了鼠標點擊而不是按鍵。

我建議為應用程序中的其他表單創建一個基本表單以繼承。 將此代碼添加到基本表單以創建名為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);
            }
        }
    }
}

此解決方案不僅適用於頂級控件,還適用於嵌套控件,例如放置在面板內的控件。

在窗體的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

我設法做到這一點的唯一方法是處理每個控件的[c] Click [/ c]事件。 我不相信在控制處理事件之前會引發事件。

在WPF中,有“隧道”預覽事件提供此功能,但這在WinForms中並沒有真正幫助您。

如果願意,您可以掛鈎所有控件的事件,然后監視這種方式。 我假設有一些超級奇特的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。

單擊表單上的空白區域很容易,但要獲得實際在控件上的單擊,您需要該控件的合作才能將其發送到表單。

一種可能性是對整個表單進行透明控制,並接受對它的點擊,處理它們,然后將它們傳遞到下面的適當控件上。

這是開發中的常見模式,稱為Observer模式。 有很多Observer模式的例子,c#這里有一個例子http://msdn.microsoft.com/en-us/library/ms954621.aspx,但有一個很好的谷歌。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM