2009-07-02 5 views
0

フォームのMouseMoveのイベントハンドラを作成しました ですが、フォームにパネルを追加すると、パネル上にマウスが移動してもこのハンドラは実行されません。 イベントハンドラをパネルに追加しましたが、これは動作しますが、フォーム上にいくつかのパネルがありました。 は簡単なソリューションですか?コントロールはC#Windowsプログラムでフォームのイベントを非表示にします

+0

何をしようとしていますか? –

+0

私は2つのパネルを持つフォームを持っています。 –

答えて

0

という名前であなたのしようとしているメッセージのプリプロセスを行いIMessageFilterをを実装することができコントロール。

http://blogs.msdn.com/csharpfaq/archive/2004/10/20/245412.aspx

はしかし、私は、これは設計の観点から物事を行うには非常にきれいな方法だとは思わない。

+0

私はその記事を読んでいるだけかもしれませんが、それは解決策です。 –

+0

これはとても便利な記事でしたが、もっと簡単な方法を探していました;) –

+0

ありがとうOG。あなたのアプローチを実装しました。 –

0

いいえ簡単な方法はなく、MouseMoveイベントを受け取る必要がある各コントロールにイベントハンドラを割り当てる必要があります。

1

ハンドラを「伝播」できる必要があると思いますので、それぞれのコードを書き直す必要はありません。 MouseMoveイベントにはのコントロール相対座標があるので、パネルからフォームにイベントを渡す場合は、イベントのX & Y値をフォーム座標に変換する必要があります(パネルを減算するようなものイベントXからの位置Xなど)。

0

フォームのCaptureプロパティをtrueに設定すると、マウスの下にあるコントロールに関係なく、すべてのマウス入力を受け取ります。特定の操作でマウスのキャプチャを失うことになります(ただし、正確なタイミングはわかりません)。また、プロパティのドキュメントに従って、マウスがキャプチャされている間、ショートカットキーは機能しません。したがって、達成したいことに応じて、これは好ましい方法ではないかもしれません。

+0

キャプチャはドラッグ操作用に予約されています。この場合、他のすべてのコントロールがマウスの相互運用性を失うためです。 – arbiter

2

残念ながら、WinFormsはイベントのバブリングをサポートしていません。しかし、イベントを取り込む作業を簡単にするためのコードを書くことができます。

public void AssignMouseMoveEvent(Form form) 
{ 
    foreach(Control control in form.Controls) 
    { 
     if(! (control is Panel)) 
      continue; 

     control.MouseMove += PanelMouseMove; 
    } 
} 

あなたはそれをあなたの現在のフォームを渡す上記のコードを呼び出す必要があり、それがすべてのパネルのMouseMoveイベントのイベントハンドラとしてPanelMouseMoveを割り当てます。

+1

PanelMouseMoveイベントハンドラのe.Locationは、MouseMoveイベントを発生させるコントロールを基準にしていることに注意してください。 –

+0

私はそれが著者が必要とするものだと思いますか? – SolutionYogi

+0

著者はフォームにすべてのマウス入力を受けたいと考えているので、マウスが動くようなコントロールではなく、フォームに相対的な座標であれば好ましいと思います。 ClientToScreenとScreenToClientの2回の呼び出しで簡単に修正できます。著者にこのことを知らせたいだけでした。 –

0

マウスがパネル上ではなくフォーム上を移動し始めると仮定すると、これは大きな前提ですが、サブコントロールに入るとMouseLeaveイベントが発生します。フォームの境界内にある場合は、カーソルの位置を確認してマウス移動コードを呼び出すことができます。

マウスの移動イベントがコントロールで開始された場合、これは機能しません。

1

このコードは(私のために働いたあなたはパネルとラベルを持つフォームを前提としています。ラベルは、「MouseCoords」

 

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void ShowCoords(int x, int y) 
     { 
      this.MouseCoords.Text = string.Format("({0}, {1})", x, y); 
     } 

     private void Form1_MouseMove(object sender, MouseEventArgs e) 
     { 
      this.ShowCoords(e.X, e.Y); 
     } 

     protected override void OnControlAdded(ControlEventArgs e) 
     { 
      // hook the mouse move of any control that is added to the form 
      base.OnControlAdded(e); 
      e.Control.MouseMove += new MouseEventHandler(Control_MouseMove); 
     } 

     private void Control_MouseMove(object sender, MouseEventArgs e) 
     { 
      // convert the mouse coords from control codes to screen coords 
      // and then to form coords 
      System.Windows.Forms.Control ctrl = (System.Windows.Forms.Control)sender; 
      Point pt = this.PointToClient(ctrl.PointToScreen(e.Location)); 
      this.ShowCoords(pt.X, pt.Y); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      this.MouseMove += this.Form1_MouseMove; 
     } 
    } 
} 
+0

私はこの技術に精通しています。しかし、多くのコントロールに同じハンドラを割り当てるときのパフォーマンスへの影響はどれですか? –

+0

テストをテストしますが、パフォーマンスの影響は最小限に抑える必要があります。一度に1つのコントロールだけがイベントハンドラを呼び出すことになります。これは、コントロールごとにデリゲートをインスタンス化していることを意味します。デリゲートは、ファンクションへのポインタ型の安全なポインタです(関数の「コードセグメント」は一度しか存在しません。参照を作成しています)。それでも、たくさんのコントロールがある場合、メモリの影響があります。テストするのは非常に簡単で、OnControlAddedメソッドをコメントアウトしてメモリ使用量を比較するだけです。 – JMarsch

+0

(oh、1 quid-pro-quo):mousemove自体の内部に何か(anythign)を実行した場合の影響は、パフォーマンスが低下する可能性があります。マウスの移動は非常に頻繁に起こります。私の以前のコメントでより正確にするために、同じハンドラを参照する複数のコントロールのコストは低くすべきだと思いますが、マウスの移動ハンドラで多くの作業を行うことで全体のパフォーマンスが影響を受ける可能性があります。 – JMarsch

0

私は別の解決策を見つけました:) "イベントを隠すコントロール内のイベントを発生させる" onMouseMoveを呼び出すことによって、パネルのイベントをキャッチしてフォームのマウス移動イベントを発生させます

関連する問題