web-dev-qa-db-ja.com

親コントロールへのパススルーマウスイベント

環境:.NET Framework 2.0、VS 2008。

特定のマウスイベント(MouseDownMouseMoveMouseUp)を親コントロールに渡す特定の.NETコントロール(ラベル、パネル)のサブクラスを作成しようとしています。 (またはトップレベルのフォームの代わりに)。これを行うには、標準コントロールのインスタンスでこれらのイベントのハンドラーを作成します。例:

_public class TheForm : Form
{
    private Label theLabel;

    private void InitializeComponent()
    {
        theLabel = new Label();
        theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown);
    }

    private void theLabel_MouseDown(object sender, MouseEventArgs e)
    {
        int xTrans = e.X + this.Location.X;
        int yTrans = e.Y + this.Location.Y;
        MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta);
        this.OnMouseDown(eTrans);
    }
}
_

親コントロールでイベントを発生させるメソッドは保護されており、親コントロールの修飾子がないため、イベントハンドラーをコントロールのサブクラスに移動することはできません。

タイプ_System.Windows.Forms.Control_の修飾子を介して保護メンバーSystem.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)にアクセスできません。修飾子は_TheProject.NoCaptureLabel_型(または派生型)でなければなりません。

私はサブクラスでコントロールのWndProcメソッドをオーバーライドすることを検討していますが、うまくいけば誰かが私にもっときれいな解決策を与えることができます。

31
GentlemanCoder

はい。多くの検索の後、記事 "Floating Controls、tooltip-style" を見つけました。これはWndProcを使用してメッセージを_WM_NCHITTEST_からHTTRANSPARENTに変更し、Controlをマウスイベントに対して透過にします。

それを実現するには、Labelから継承されたコントロールを作成し、次のコードを追加します。

_protected override void WndProc(ref Message m)
{
    const int WM_NCHITTEST = 0x0084;
    const int HTTRANSPARENT = (-1);

    if (m.Msg == WM_NCHITTEST)
    {
        m.Result = (IntPtr)HTTRANSPARENT;
    }
    else
    {
        base.WndProc(ref m);
    }
}
_

これは、.NET Framework 4 Client Profileを使用してVisual Studio 2010でテストしました。

64
akatran

基本クラスでpublic/protectedメソッドを作成して、イベントを発生させる必要があります。次に、派生クラスからこのメソッドを呼び出します。

OR

これは、あなたの望むことですか?

public class MyLabel : Label
{
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        //Do derived class stuff here
    }
}
3
Autodidact

WS_EX_TRANSPARENT拡張ウィンドウスタイルは実際にこれを行います(インプレースツールチップが使用するものです)。多くのハンドラーをコーディングしてそれを行うのではなく、このスタイルを適用することを検討してください。

これを行うには、CreateParamsメソッドをオーバーライドします。

protected override CreateParams CreateParams
{
  get
  {
    CreateParams cp=base.CreateParams;
    cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
    return cp;
  }
}

さらに読むには:

3
Jeff Yates