7

ユーザーが System.Windows.Forms.Form の外側をクリックした場合、 System.Windows.Forms.Form を閉じたいと思います。IMessageFilter を使用してみましたが、それでも PreFilterMessage にメッセージが渡されません。フォームのウィンドウ外でクリックを受け取るにはどうすればよいですか?

4

8 に答える 8

8

フォームの Deactivate イベントに、「this.Close()」を配置します。Windows の他の場所をクリックするとすぐにフォームが閉じます。

更新: あなたが今持っているのはボリューム ボタンだと思います。Click イベント内で VolumeSlider フォームのインスタンスを作成し、ユーザーがポップアップ フォームを閉じるまでブロックする ShowDialog() を呼び出して表示させます。次の行では、ユーザーが選択したボリュームを読み取り、プログラムで使用します。

これは問題ありませんが、お気づきのように、ユーザーはメイン プログラムに戻るために明示的にポップアップを閉じる必要があります。Show() は、ポップアップ フォームで実際に使用したいメソッドですが、Show() はブロックされません。つまり、メイン フォームに戻る Click イベントは、新しいボリュームがどうあるべきかを知らずに終了します。

簡単な解決策は、次のようにメイン フォームにパブリック メソッドを作成することです。

public void SetVolume(int volume)
{
    // do something with the volume - whatever you did before with it
}

次に、ボリューム ボタンのクリック イベント (メイン フォームでも) で、VolumeSlider を次のように表示します。

VolumeSlider slider = new VolumeSlider();
slider.Show(this); // the "this" is needed for the next step

VolumeSlider フォームでは、ユーザーが (私が推測する) スクロールバーを操作するときに、このコードをスクロールバーの ValueChanged イベントに配置します (それがそのようなものだと思います)。

MainForm owner = (MainForm)this.Owner;
owner.SetVolume(scrollbar.Value);

次に、VolumeSlider フォームの Deactivate イベントに、上記のように this.Close() を配置します。その後、フォームは期待どおりに動作します。

于 2008-11-18T11:36:51.803 に答える
5

この質問の p-daddy のおかげで、ShowDialog を使用できるこのソリューションを見つけました。

protected override void OnShown(EventArgs e)
{
    base.OnShown(e);
    this.Capture = true;
}

protected override void OnCaptureChanged(EventArgs e)
{
    if (!this.Capture)
    {
        if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position))
        {
            this.Close();
        }
        else
        {
            this.Capture = true;
        }
    }

    base.OnCaptureChanged(e);
}
于 2008-11-19T08:57:51.983 に答える
4

サイモンのソリューションでは、ノームによる同じ問題の説明がありました。次のコードで、「クリックスルー」の問題を回避しました...

protected override void WndProc(ref Message m)
{    
    base.WndProc(ref m);

    // if click outside dialog -> Close Dlg
    if (m.Msg == NativeConstants.WM_NCACTIVATE) //0x86
    {
        if (this.Visible)
        {
            if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position))
                this.Close();
        }
    }
}
于 2012-07-31T15:10:04.813 に答える
0

コントロールと対話できることを除いて、メニューのように動作するポップアップ ウィンドウを作成しようとしている場合は、ツールストリップ ドロップダウン内でユーザー コントロールをホストしてみてください。

于 2008-11-18T12:18:47.693 に答える
0

それが MDI アプリケーションの子フォームである場合、親フォームでクリックをトラップできます。そうしないと、ソリューションが乱雑になります。

とにかく、あなたが提案するものが直感的なUIの動作を表しているとは確信していません。それが最高のデザインだと確信していますか?

于 2008-11-18T11:32:09.377 に答える