【问题标题】:Can't set DialogResult in WPF无法在 WPF 中设置 DialogResult
【发布时间】:2010-10-28 06:36:59
【问题描述】:

我在调用窗口中使用 ShowDialog() 显示 WPF 窗口。窗口打开并且是模态的,如预期的那样。但是,在对话框窗口中的“确定”和“取消”按钮的单击事件中,我分别设置了 this.DialogResult = true (或 false),并且没有设置该值。窗口按预期关闭,但 DialogResult 仍然为空。

这是 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;

【问题讨论】:

  • 如何将 DialogResult 设置为布尔值?它应该是一个枚举,比如 DialogResult.OK
  • 不,在 WPF 中,如果你用它的 ShowDialog() 方法打开一个 Window 对象,你可以将 DialogResult 设置为布尔值。
  • 您可以在这里发布您的<Window ... /> 定义的内容吗?也许这与您初始化窗口的方式有关。
  • 那个Window2是什么?您是否从 Window 派生了自己的 Window 类?那么你的Window2类可能有问题,你应该发布它的源代码。
  • 我刚刚遇到了这个问题,从您自己的 Window 类派生时,这似乎是一个错误。不知道如何解决。

标签: c# wpf modal-dialog dialogresult


【解决方案1】:

DialogResult 是一个可为空的布尔值。但是,您不必强制转换它来获得它的价值。

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

??如果结果为空,则设置要返回的默认值。更多信息: Using Nullable Types (C# Programming Guide)

至于最初的问题,我唯一一次看到并追踪到这个问题是在设置 DialogResult 和关闭窗口之间设置窗口时。不幸的是,我能提供的唯一建议是让您逐步检查代码并检查操作的顺序。我相信我通过设置DialogResult 然后显式关闭窗口来“修复”它。

【讨论】:

  • 当时没有配置窗口。
  • 没错。我的一个朋友使用 result.Value 来判断真假。
  • 我更喜欢result == true。我认为它更具可读性,我不得不考虑??在这里做了什么。
  • result == true 是我最讨厌的。 == true 是隐含的。如果您正在寻找增强的可读性,我建议您根据它们所代表的内容命名您的变量。例如:bool? isOK = myWindow.Dialog(); if (isOK ?? false) { ... }
  • == true 从不隐含 bool?
【解决方案2】:

首先你必须考虑到它返回一个可为空的布尔值(布尔值?),所以为了比较它或将它设置为另一个变量,你必须将它转换为一个普通的布尔值

bool result = (bool)myWindow.DialogResult;

至于它为空......我不明白为什么会发生这种情况,除非它在设置为真或假之后以某种方式被设置回空。你能展示你的代码吗?

编辑:

您的代码对我来说很好,这是我在第二个窗口中的内容:

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

有什么大的不同吗?

【讨论】:

  • 在调试会话中,我将 DialogResult 设置为 true 后立即检查它的值,它仍然为空。
  • 没有区别。事实上,我对同一个项目中的其他几个窗口做同样的事情,它们都工作正常。
  • 尝试使用布尔?结果 = win.DialogResult;在 win.ShowDialog() 之后...我知道这并不乐观,但让我们尝试一下。您认为我可能需要重新创建场景是否有更多信息?这是一些奇怪的行为......
  • @quinnapi haha​​ 2 年后,我遇到了同样的问题。我刚刚意识到我正在阅读自己的答案。烦人!
  • @Carlo - 看看stackoverflow.com/a/1759505/319980,这是一种用简单的附加属性替换那些代码隐藏事件处理程序的非常优雅的方法。
【解决方案3】:

我刚刚完全遇到了同样的问题,这似乎是由于我重写了 OnClosing() 方法引起的。我需要重写 OnClosing() 以阻止用户通过关闭 (X) 按钮关闭模式窗口。

当我注释掉 OnClosing() 方法时,问题就消失了,DialogResult 返回了预期的真或假值。

感兴趣的是我的按钮点击处理程序和 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;
    }
}

【讨论】:

  • 作为对此的后续,我刚刚从窗口中删除了关闭 (x) 按钮,因此我不再需要覆盖 OnClosing()。更多信息:stackoverflow.com/questions/743906/…
  • 即使关闭 (x) 按钮被隐藏,用户仍然可以通过按 Alt-F4 或单击“IsCancel”属性设置为“True”的按钮来关闭窗口。
  • 我有类似的问题。你的帖子有帮助!谢谢!
  • 我遇到了同样的麻烦,感谢@dodgy_coder,我找到了问题的根源。 DialogResult 设置器调用 Close link。您的 OnClosing 事件处理程序设置 e.Cancel 显然会重置 DialogResult。解决方法是先设置buttonHasBeenClicked(防止取消关闭),再设置DialogResult
【解决方案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;
        }

【讨论】:

  • 在查看了其中几个答案后,我最终也这样做了。它很难看,需要文档和 cmets,但这是避免 WPF 踩到我的唯一方法。
【解决方案5】:

在设置 DialogResult 之前是否关闭窗口? 您应该发布按钮事件处理程序的全部内容。

【讨论】:

  • 我认为这是对的。我们解决这个问题的唯一方法是查看更多上下文。
【解决方案6】:

我也遇到了这个问题。事实证明,我在 IF 语句的大括号内设置了 DialogResult,因此(尽管看起来很奇怪)导致了错误。删除这一行后,问题就解决了。

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】:

      问题在于表单的生命周期:

      对话事件 私人无效_loginViewModel_LoginEvent(对象发送者,LoginViewModel.LoginEventArgs e) { 对话结果=真; this.Close(); }

      作品:

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

      不起作用:

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

      【讨论】:

        【解决方案9】:

        我通过添加this.close() 解决了这个问题,然后添加this.DialogResult=truewindow.ShowDialog() 返回true

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

        【讨论】:

          【解决方案10】:

          我遇到了类似的问题,但我的问题来自我结束语中的代码。我试图在窗口关闭之前 Dispose() 一个 List,然后将 List 属性设置为 null ......在我的 set 属性方法中遵循笨拙的解决方法,之后一切正常:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-10-07
            • 2011-09-10
            • 1970-01-01
            • 2013-01-26
            • 1970-01-01
            • 1970-01-01
            • 2010-11-26
            相关资源
            最近更新 更多