3

奇妙に聞こえるかもしれませんが、これは私の趣味のためです。(カスタム)メッセージボックスに、理想的にはコードをブロックするYesNoボタンが表示されるようにしたいと思います。ただし、親フォームをクリックして、メッセージ ボックス ボタンを特にクリックしなくてもメッセージ ボックスを閉じることができるようにする必要があります (メッセージ ボックスで [いいえ] をクリックするのと同じです)。

このようなもの:

     void Foo()
     {
         CustomMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
         //block the code here, but user should be able to click on form, so that its equivalent to have clicked No;
         //if clicked No, return;

         //delete.
     }

だから私が考えた解決策は、カスタムメッセージボックスを非モーダルにすることでした-ユーザーがフォームをクリックできるようにしますが、コードをブロックすることはできません..どうすればできますか?

次のようになります。

 void Foo()
 {
     NonModalMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
     //block thread till user clicks on form or messagebox buttons.
     //unblock when user clicks.
     //if No, return;

     //delete.
 }

編集:これは標準的な慣行ではないことを知っており、非モーダル フォームはブロックされませんが、モーダル フォームはブロックされます。したがって、モーダル フォームまたは非モーダル フォームの動作に満足することはお勧めしません。私の質問は、Windows フォームでContextMenuの動作をシミュレートする方法があるということです。

4

6 に答える 6

3

これは非常に簡単に解決できます。モーダルダイアログを作成して使用しますが、ダイアログのWndProcをオーバーライドして、WM_MOUSEDOWNイベントを処理します。マウスの下の位置を確認し、それが親ウィンドウ上にあるがダイアログ自体の上にはない場合は、単にダイアログを閉じます。

于 2011-12-19T21:26:20.230 に答える
2

基本的に、「ブロッキング」呼び出しでこれを簡単に行うことはできません。簡単にできることは、削除を実行するために必要な情報を渡すか、操作を実行するデリゲートをフォームに渡すことです。ユーザーが [OK] をクリックすると、操作を実行するだけです。親フォームをアクティブ化したら、子フォームを閉じます。

于 2011-12-19T21:16:52.857 に答える
1

これを処理する別の方法は、ここからShowDialog を呼び出すときに親フォームを手動で有効にすることです。

[DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr hWnd, bool enable);

internal static DialogResult ShowDialogSpecial(this Form formToBeShown, Form parent)
{
    parent.BeginInvoke(new Action(() => EnableWindow(parent.Handle, true)));
    formToBeShown.ShowDialog(parent);

    return formToBeShown.DialogResult;
}

次のように、任意の親フォームから拡張メソッドを呼び出すだけです。

var f = new Form();
f.ShowDialogSpecial(this);
//blocks but parent window will be active.

もちろん、子フォームを閉じるには、親フォームのクリックを処理する必要があります。

于 2012-09-05T15:09:03.423 に答える
1

ユーザーがバックグラウンド ウィンドウをクリックしてダイアログ ボックスをキャンセルできるようにしたいですか? バックグラウンド ウィンドウにハンドラーを追加して、ユーザーがクリックしたときに、非モーダル ウィンドウが表示されているかどうかを確認し、表示されている場合は閉じるようにします。

簡単に聞こえますが、バックグラウンド ウィンドウと子ウィンドウで可能なすべてのクリックを処理するように注意する必要があります。それは私が降りたくないワームの缶のように聞こえます。

おそらく代わりに、非モーダル ダイアログ ボックスがフォーカスを失ったかどうかを検出して、自動的に閉じることができます。単純な「削除の確認」ダイアログ ボックスでは、この動作が理にかなっていることがわかりますが、ユーザーとしての私の最初の反応は、ESC キーを連打してダイアログ ボックスを閉じることです。

于 2011-12-19T21:19:34.193 に答える
0

もっと簡単な方法: フォームの "TopMost" プロパティを True に設定します。その後、ブロッキングのように動作します

于 2016-02-22T08:29:55.480 に答える
0

次のようなことができます。

public void ShowMe() {
    Show();
    while (!_receivedDeactivateEvent)
        Application.DoEvents();
}

ただし、それをお勧めするかどうかはわかりません-それがどれほど安定するかはわかりませんし、「 dialog' が起動しています (最初のダイアログを最初に閉じますか、それとも残しますか? 後者の場合があり、混乱する可能性があります)。

于 2011-12-19T21:19:55.597 に答える