Невозможно установить DialogResult в WPF

Я показываю окно WPF, используя ShowDialog() из вызывающего окна. Окно открывается и является модальным, как ожидалось. Тем не менее, в моей кнопке "ОК" и "Отмена" нажмите события в диалоговом окне, я установил 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;

Ответ 1

DialogResult - это nullable bool. Однако вам не нужно бросать его, чтобы получить его значение.

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

устанавливает значение по умолчанию для возврата, если результат равен нулю. Больше информации: Использование Nullable Types (Руководство по программированию на С#)

Что касается исходного вопроса, единственный раз, когда я видел и отслеживал эту проблему, - это когда окно было расположено между установкой DialogResult и закрытием окна. К сожалению, единственный совет, который я могу предложить, - это пройти через свой код и проверить порядок операций. Я считаю, что я "исправил" его, установив DialogResult, а затем явно закрывая окно.

Ответ 2

Ну, в первую очередь, вы должны учесть, что он возвращает nullable bool (bool?), поэтому для того, чтобы сравнить его или установить его на другую переменную, вы должны отправить его в обычный bool

bool result = (bool)myWindow.DialogResult;

Что касается того, что он является нулевым... Я не понимаю, почему это должно произойти, если только оно каким-то образом не возвращается к нулю. После того, как оно установлено в true или false. Можете ли вы показать свой код?

EDIT:

Ваш код работал отлично для меня, это то, что у меня есть во втором окне:

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
    }
}

Есть ли какая-то большая разница?

Ответ 3

У меня только что была точно та же проблема, и это, по-видимому, вызвано переопределением метода OnClosing(). Мне нужно было переопределить OnClosing(), чтобы пользователь не закрыл модальное окно с помощью кнопки закрытия (X).

Когда я комментирую метод 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;
    }
}

Ответ 4

Я тоже попал в эту проблему, и единственный способ, которым я нашел исправление, - использовать этот код в моем классе:

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;
        }

Ответ 5

Закрываете ли вы окно перед установкой DialogResult? Вы должны опубликовать весь контент обработчиков событий кнопок.

Ответ 6

Я тоже столкнулся с проблемой. Оказывается, я установил 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;
    }

Ответ 7

У меня на странице диалогового окна есть следующее. (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"
}

Ответ 8

У меня была аналогичная проблема, но моя проблема исходила из кода в моей заключительной заявке. Я пытался Dispose() List перед закрытым окном, а затем установить свойство List < > равным null... он задыхался от свойства set, когда я пытался установить его значение в null, поэтому я придумал после неуклюжего обходного пути в моем методе свойств объекта и после него все работало:

    List<SettingItem> settingItems;
    public IEnumerable<SettingItem> Settings
    {
        get
        {
            return settingItems.OrderBy(t => t.Name).AsEnumerable();
        }
        set
        {
            if (value == null)
            {
                settingItems.Clear();
            }
            else
            {
                settingItems = value.ToList();
            }
        }
    }