在为表单关闭实现WPF MVVM模式时,获取“只能在创建Window并显示为对话框后才能设置DialogResult”

时间:2011-11-30 12:43:58

标签: .net wpf

我正在尝试为WPF表单关闭实现this MVVM模式,这也在此blog中进行了解释,我收到System.InvalidOperationException并显示错误消息" DialogResult只能设置在创建Window并显示为对话框之后。"当我尝试在关闭按钮命令上设置对话框结果时:

DialogResult = true;

这是我的ViewModel:

class MainWindowViewModel:INotifyPropertyChanged
{
    private bool? dialogResult;
    public bool? DialogResult
    {
        get { return dialogResult; }
        set
        {
            if (value != this.dialogResult)
            {
                this.dialogResult = value;
                OnPropertyChanged("DialogResult");
            }
        }
    }

    public string Text
    {
        get { return "Hello!"; }
    }

    void CloseCommandExecute()
    {
        this.DialogResult = true;
    } 

以下是XAML视图:

<Window x:Class="WpfApplication.Mvvm.Windowclosing.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication.Mvvm.Windowclosing"
        local:DialogCloser.DialogResult="{Binding DialogResult}"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Text}" Grid.Row="0"/>
        <Button Grid.Row="1" Command="{Binding CloseCommand}">Close Me</Button>
    </Grid>
</Window>

我在这里做错了什么?

10 个答案:

答案 0 :(得分:23)

设置对话框结果仅在使用ShowDialog()打开表单时有效。当您尝试在使用Show()打开的表单上设置对话框结果时,会出现此错误。

答案 1 :(得分:15)

当我创建一个通过ShowDialog()调用的窗口时,我遇到了这个问题。在窗口中,我有一个Ok_Clicked,其中包含一堆语句。为了保证&#39;如果有任何错误我首先将DialogResult初始化为false,则对话框返回false。如果一切正常,我会将DialogResult设置为true并关闭窗口。我一直得到同样的例外。

我了解到如果DialogResult未设置为true,ShowDialog将始终返回false。当我在DialogResult = false的开头删除Ok_Clicked时,我不再获得异常。

答案 2 :(得分:9)

我遇到了一个可能对其他人有帮助的替代答案。在设置DialogResult之前,我最终在窗口上调用了Close()。确保你不这样做 - 它会导致这个错误。

答案 3 :(得分:6)

对于使用 ShowDialog 的用户,您可以从按钮中移除属性:

<强> IsCancel =真 和 的 ISDEFAULT =真

答案 4 :(得分:1)

由于绑定,您试图过早设置Window.DialogResult。据推测,您的DialogCloser.DialogResult(您尚未向我们展示)实施工具也会在DialogResult上设置Window。尝试将绑定模式更改为OneWayToSource,以便更改仅传播到您的VM,而不是相反:

local:DialogCloser.DialogResult="{Binding DialogResult, Mode=OneWayToSource}"

或者,如果将Window.DialogResult显示为对话框,则只需将行为更改为仅设置Window即可。很难说没有看到一切。

答案 5 :(得分:1)

我有

IsDefault="True"
多个按钮上定义的

属性。

答案 6 :(得分:0)

我遇到了同样的问题,使用ShowDialog()并在调用close之前设置结果。

然而,我所做的是在设置结果之前隐藏对话框。 因此,当设置DialogResult时,Visibility必须设置为Visible,Hidden和Collapsed都会给你一个误导性的错误,即只有在创建Window并显示为对话框后才能设置DialogResult。&#34;。

答案 7 :(得分:0)

对我来说,就像贾维斯(Jarvis)一样,此错误是由在通过ShowDialog()显示的窗口调用Close()之后设置DialogResult引起的。

就我而言,这是因为我正在将代码从WinForms移植到WPF。这种顺序在WinForms中可以正常工作,但是WPF不喜欢它。

我尝试了其他修复程序,例如从按钮中删除了isDefault和isCancel属性,但是这些无效。

答案 8 :(得分:0)

我知道这个线程已经很老了,但是今天我遇到了同样的问题。我做错的是,我用ShowDialog()打开了一个新窗口,而不是用Close()关闭了新窗口,并试图将DialogResult设置为True。

但是,如果仅将DialogResult设置为True,这已经足够了,然后Window将自动关闭,并且不需要调用Close()方法。

答案 9 :(得分:0)

我遇到此错误,并通过在click事件处理程序中的任何其他代码之前设置DialogResult来解决此错误。当它结束时,就在Close之前,我会得到错误。但是从一开始就可以使用。希望这会对某人有所帮助,这让我发疯了,直到我终于开始工作。