web-dev-qa-db-ja.com

WPFでDialogResultを設定できません

呼び出しウィンドウからShowDialog()を使用してWPFウィンドウを表示します。ウィンドウが開き、予想どおりモーダルです。ただし、ダイアログウィンドウの[OK]ボタンと[キャンセル]ボタンのクリックイベントで、それぞれthis.DialogResult = true(またはfalse)を設定すると、値は設定されません。ウィンドウは期待どおりに閉じますが、DialogResultはまだnullです。

これはWPFのバグですか?または、DialogResultプロパティを設定できないが、例外をスローしない理由はありますか?ウィンドウはブラウザでホストされていません。

呼び出しウィンドウのコード:

Window2 win = new Window2();
bool? result = win.ShowDialog();
if (result.HasValue && result.Value) {
   //never gets here because result is always null
}

ダイアログウィンドウのコード:

this.DialogResult = true;
29
quinnapi

DialogResultはNULL可能ブールです。ただし、値を取得するためにキャストする必要はありません。

bool? result = myWindow.ShowDialog();
if (result ?? false)
{
  // snip
}

??結果がnullの場合に返すデフォルト値を設定します。詳細: Nullable型の使用(C#プログラミングガイド)

元の質問に関しては、この問題を確認してトレースしたのは、DialogResultの設定からウィンドウを閉じるまでの間にウィンドウが破棄されたときだけです。残念ながら、私が提供できる唯一のアドバイスは、コードをステップスルーして操作の順序を確認することです。 DialogResultを設定してからウィンドウを明示的に閉じることで「修正」したと思います。

18
Dennis

まず最初に、null可能bool(bool?)を返すことを考慮する必要があるため、それを比較したり、別の変数に設定するには、通常のboolにキャストする必要があります。

bool result = (bool)myWindow.DialogResult;

それがnullであることについては、それがtrueまたはfalseに設定された後にnullに設定されない限り、なぜそれが起こるべきかわかりません。コードを見せてもらえますか?

編集:

あなたのコードは私のためにうまくいきました、これは私が2番目のウィンドウに持っているものです:

private void button2_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = false;
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}

そして、Window1で:

private void window1_Loaded(object sender, RoutedEventArgs e)
{
    Window2 win = new Window2();

    bool? result = win.ShowDialog();

    if (result.HasValue && result.Value)
    {
        //it DID get here
    }
}

大きな違いはありますか?

11
Carlo

正確に同じ問題が発生したばかりで、OnClosing()メソッドをオーバーライドしたことが原因のようです。ユーザーが閉じる(X)ボタンでモーダルウィンドウを閉じるのを止めるには、OnClosing()をオーバーライドする必要がありました。

OnClosing()メソッドをコメントアウトすると、問題はなくなり、DialogResultが返され、trueまたはfalseの期待値が設定どおりに返されます。

興味深いのは、ボタンクリックハンドラーとOnClosingメソッドです。

private void AlternateButton_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = false;
    buttonHasBeenClicked = true;
    this.Close();
}

private void DefaultButton_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
    buttonHasBeenClicked = true;
    this.Close();
}

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);
    if (!buttonHasBeenClicked)
    {
        // Prevent the user closing the window without pressing one of the buttons.
        e.Cancel = true;
    }
}
8
dodgy_coder

私もこの問題に取り組んできましたが、それを修正する唯一の方法は、私のクラスでこのコードを使用することでした:

public new bool? DialogResult { get; set; }

そして、DialogResultを設定した後、それは私のためにうまくいきます!! (非常に奇妙な問題)。これは私が使用していたコードでした:

cmdCancel = new RelayCommand(() => { DataContact.Reload(); this.DialogResult = false; this.Close(); });

ダイアログを開くには:

public static MessageBoxResult ShowQuestionYesNo(string message)
        {
            POLMessageBox w = new POLMessageBox("سوال", MessageBoxType.QuestionYesNo, message);
            w.ShowDialog();
            var b = w.DialogResult;
            if (b == true) return MessageBoxResult.Yes;
            if (b == false) return MessageBoxResult.No;
            return MessageBoxResult.No;
        }

DialogResultを設定する前にウィンドウを閉じますか?ボタンイベントハンドラーのコンテンツ全体を投稿する必要があります。

2
batzen

問題はフォームの寿命によるものです:

ダイアログイベント private void _loginViewModel_LoginEvent(object sender、LoginViewModel.LoginEventArgs e){DialogResult = true; this.Close(); }

作品:

var login = new Login();
var result = login.ShowDialog();

動作しません:

var result = new Login().ShowDialog();
0
jlo-gmail

私も問題に遭遇しました。 DialogResultをIFステートメントのブレース内に設定していたため、この理由で(見かけ上奇妙なように)エラーが発生しました。この単一行が削除されるとすぐに、問題は解決しました。

private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        if (!string.IsNullOrEmpty(startBlockPosBox.Text))
        {
          .. do stuff ..
        }
        else
        {
          .. do stuff ..
          DialogResult = true; // this line caused the problem
        }

        DialogResult = true;
    }
0
dracore

ダイアログウィンドウページに次のように表示されます。 (dialogwindow.xaml.cs)

   private void dlgWindowYesButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
        this.Close();
    }

    private void dlgWindowNoButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;
        this.Close();
    }

呼び出しページでは、次のようなダイアログウィンドウを使用しました。

dialogwindow dWinObj = new dialogwindow();
if(dWinObj.ShowDialog().Value == true)
{
  //perform the operation when the user clicks "Yes"
}
0
Kishore