16

WPFアプリケーションでのこの非常に奇妙な動作に気づきました。

fromMainWindowを使用して表示される、があります。を使用して、(非モーダル)を開くことができます。のはに設定されます。Show()App.OnStartupMainWindowSubWindowShow()SubWindowOwnerMainWindow

SubWindow閉じていると、MainWindow再び表示されます(良好)。

一部のアクションでは、 (に設定されている)SubWindowを使用して、モーダルダイアログとして3番目のウィンドウを開くことができます。そのモーダルダイアログがの存続期間中に少なくとも1回開閉されると、奇妙なことが起こります。ShowDialog()OwnerSubWindowSubWindow

閉じた後SubWindowMainWindow表示されません。代わりに、背後にある ランダムなウィンドウがMainWindow表示されます。なぜこれが起こるのか、そしてそれを修正する方法を誰かが私に説明できますか?

Windowモーダルダイアログが、を使用して表示される通常のダイアログであるか、を使用して表示されるShowDialog()メッセージボックスであるかは関係ありませんMessageBox.Show()


これを再現するための最小限のコードを次に示します。Visual Studioで新しいWPFアプリケーションを作成し、これを事前に生成されたMainWindow.xaml.csに貼り付けます

次に、キーボードのキーを押して1つのウィンドウのみを開き、閉じて、期待どおりの動作をします。2つのキーを押して両方を閉じると、最初のウィンドウがVisual Studioの背後にあります(おそらく)。

public MainWindow()
{
    InitializeComponent();
    this.PreviewKeyDown += (sender, e) =>
    {
        if (this.Owner is MainWindow)
        {
            // we're the SubWindow

            MessageBox.Show("I am a modal dialog");

            // code below produces the exact same behavior as the message box

            //var dialog = new MainWindow();
            //dialog.Owner = this;
            //dialog.ShowDialog();
        }
        else
        {
            // we're the initial MainWindow created by App.
            var subWindow = new MainWindow();
            subWindow.Owner = this;
            subWindow.Show();
        }
    };
}
4

5 に答える 5

13

これはかなり厄介なWPFのバグであり、それを引き起こすコードに欠陥は見つかりませんでしたが、フォーカシングを扱うソースコードには「これを理解する必要があります」というコメントがたくさんあります。単なる回避策であり、理想的とは言えませんが、ウィンドウが閉じているときに所有者に明示的にフォーカスを与えることで解決できます。このコードをコピーしてSubWindowクラスに貼り付けます。

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e) {
        base.OnClosing(e);
        if (!e.Cancel && this.Owner != null) this.Owner.Focus();
    }
于 2012-11-03T14:16:05.740 に答える
0

ウィンドウを非表示にするだけで同じ問題が発生します。この状況でClosingと同等のイベントがあることはわかりませんが、とにかくこれは機能します。

        if (Owner != null) Owner.Focus();
        Hide();
于 2013-06-26T15:43:24.653 に答える
0

this.Owner.Focus(); 私のために働いていませんそれはまだ後ろの窓に行きます私は少し遊んでTopMostを使おうとしました、TopMostの問題はそれを閉じた後にそれをfalseに戻す必要があることです。OnClosingイベントとOnClosedイベントの両方を使用しました。

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);
    if (!e.Cancel && this.Owner != null) this.Owner.TopMost = true;
}

protected override void OnClosed(EventArgs e)
{
    base.OnClosed(e);
    if (this.Owner != null)
    {
        this.Owner.TopMost = false;
    }
}
于 2018-04-20T19:57:17.837 に答える
0

WinFoms(.NET 4.7+)でも同じ問題が発生しました。私の回避策は、最初に最初のダイアログを閉じて(そのCloseメソッドを呼び出して)、その後に2番目のダイアログを表示することでした。

  1. メインフォームが開きますFirstForm
  2. FirstForm開いSecondFormて問題を引き起こします!

回避策

Close内のメソッドを呼び出します。これにより、 :FirstFormが開きます。SecondForm

// FirstForm.cs

using(var secondForm = new SecondForm())
{
    Close(); // <- this closes FirstForm instance
    secondForm.ShowDialog(owner: mainFormInstance);
}

HTH

于 2019-06-17T05:02:32.183 に答える
0

古い質問ですが、Owner.Focus()が機能しなかったため、C#WinFormsアプリケーションで機能したものを共有すると思いました。

これはDarenのTopMost修正のバリエーションですが、実際にはTopMostをtrueに設定して戻す必要はないことがわかりました。それ自体に設定するだけで、親ウィンドウが他のアプリケーションの背後に表示されなくなるのを防ぐことができます。

protected override void OnClosing(CancelEventArgs e) {
    if (Owner != null)
        Owner.TopMost = Owner.TopMost;
    base.OnClosing(e);
}
于 2020-07-10T21:26:06.230 に答える