不关闭对话框的情况下设置DialogResult

4
正如标题所说,是否有办法在不关闭对话框的情况下设置DialogResult?
可能的简单答案是否定的,但即使如此,为什么呢?DialogResult背后的行为是什么?有没有办法覆盖它。
对于任何人提出为什么需要这样做的问题,简单的回答是好奇心。这种好奇心背后的“历史”是,我正在尝试从我的ViewModel调用对话框窗口。我的方法是以下内容的混合: 在对话框具有返回值(True(Ok)/ False(Cancel))的情况下,我需要将该值(来自对话框viewModel)传递给处理对话框的类,然后将其设置为DialogResult,以便父窗口/控件在对话框返回/关闭时获取它。
测试它的最小代码片段如下:
dialog.DialogResult = TheResult;
Debug.WriteLine("Dialog Closed");
dialog.Close();

虽然这并不会导致失败,但当“Dialog Closed”被输出打印后,在调用dialog.Close();之前,对话框会关闭。如果我重写Window.Closing事件,我可以看到在调用dialog.DialogResult时它被触发,但在随后调用dialog.Close();时却没有被触发。
注意:正如我所说,整个问题只是出于好奇,因为上面的代码可以正常工作,并且不会破坏期望的功能。

你确定在实际调用 Close() 之前它已经关闭了吗?有出现任何异常吗?你能展示更多的代码吗? - Patrick Hofman
@PatrickHofman 我添加了更多信息。我认为我的其余代码是无关紧要的。此外,我没有任何异常。 - Athafoud
@PatrickHofman 是的!通过设置 DialogResult,它会自动关闭窗口!这对我来说是全新的。我已经设置了 DialogResult 并立即使用 Close() 6年了!来源:https://learn.microsoft.com/en-us/dotnet/api/system.windows.window.close?view=netframework-4.8#remarks,引用:“对话框上的“确定”和“取消”按钮也是由开发人员提供的,尽管可能会设置 DialogResult,这将自动关闭通过调用 ShowDialog 打开的窗口。” - Jogge
2个回答

5

这是设计之意,设置 DialogResult 将关闭对话框。请查看 Window.DialogResult 的源代码

    public Nullable<bool> DialogResult
    {
        get
        {
           ....
        }
        set
        {
             ....
                if (_dialogResult != value)
                {
                    _dialogResult = value;                       
                    if(_isClosing == false)
                    {
                        Close();
                    }
                }
             ...
            }                
        }
    }

1
这是预期的行为。请看下面。

https://marlongrech.wordpress.com/2008/05/28/wpf-dialogs-and-dialogresult/

具体来说...
“一旦您在窗口上设置了此属性,窗口将自动关闭,并且ShowDialog方法将返回您在DialogResult属性中设置的结果。
因为DialogResult返回对话框的结果,所以设置DialogResult的值会标志着对话框的结束使用。
设置DialogResult触发了Close。一旦当前方法完成,对话框将被关闭。这意味着Debug.WriteLine和dialog.Close()也会被执行。
如果您在按钮单击中运行以下内容,您将看到相同的结果。”
this.Close();
MessageBox.Show("TEST");
this.Close();

第一次调用Close将触发关闭并触发Closing和Closed事件,代码继续执行,因此消息框被显示,第二次调用Close被忽略,因为已经调用了关闭。它不会触发任何其他事件。
这是我测试的代码,在App.xaml.cs的OnStartup事件中使用ShowDialog打开MainWindow。
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
        //Or call Close
        //this.Close();

        MessageBox.Show("TEST");

        this.Close();
    }

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        MessageBox.Show("Window_Closing");
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        MessageBox.Show("Window_Closed");
    }
}

在我的情况下,关闭和已关闭事件被触发,代码继续执行,但是消息框不再显示。 - Athafoud
在你的情况下,MessageBox 没有显示出来,这很奇怪。我更新了我的答案,并附上了我测试过的简单代码。当我点击按钮时,我会看到 "Window_Closing",然后对话框消失,接着我会看到 "Window_Closed",然后是 "TEST",最后应用程序关闭。 - Marc
这也是我的测试案例,我们得到了相同的结果,对话框在 DialogResult = 上消失。 - Athafoud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接