子コントロールのマウス・キーボードのイベントをフォームで受け取る

MouseDown・MouseMove・MouseDown等のマウスイベントは、各コントロールで発生する為、
親フォームで一括して受信するには、明示的にイベントハンドラを設定する必要がある。

        public Form1()
        {
            InitializeComponent();

            // 親フォームのマウスイベントハンドラの割り当て
            SetEventHandler(this);
        }

        /// <summary>
        /// 子コントロールにMouseイベントハンドラを設定(再帰)
        /// </summary>
        private void SetEventHandler(Control objControl)
        {
            // イベントの設定
            // (親フォームにはすでにデザイナでマウスのイベントハンドラが割り当ててあるので除外)
            if(objControl != this)
            {
                objControl.MouseDown += (sender, e) => this.OnMouseDown(e);
                objControl.MouseMove += (sender, e) => this.OnMouseMove(e);
                objControl.MouseUp += (sender, e) => this.OnMouseUp(e);
            }

            // さらに子コントロールを検出する
            if(objControl.Controls.Count > 0)
            {
                foreach(Control objChildControl in objControl.Controls)
                {
                    SetEventHandler(objChildControl);
                }
            }
        }

        #region FormのMouseイベント受信部

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            // senderは常にFormだが、eの座標は各コントロールを基準とした座標が入る為、
            // スクリーン座標からクライアント座標を計算すること
            Point pntScreen = Control.MousePosition;
            Point pntForm = this.PointToClient(pntScreen);

            this.Text = "X=" + pntForm.X + " Y=" + pntForm.Y;
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            Point pntScreen = Control.MousePosition;
            Point pntForm = this.PointToClient(pntScreen);

            this.Text = "X=" + pntForm.X + " Y=" + pntForm.Y;
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            Point pntScreen = Control.MousePosition;
            Point pntForm = this.PointToClient(pntScreen);

            this.Text = "X=" + pntForm.X + " Y=" + pntForm.Y;
        }

        #endregion

 

キーボードのイベントも各コントロールで発生するが、
こちらは親フォームでイベントを発生させるプロパティが用意されている。

            // 子・孫問わず、すべてのコントロールで発生したキーイベントが親フォームで取得できる
            this.KeyPreview = true;