WPF Tips: Window.ShowDialog()方法:Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelp

11 篇文章 0 订阅

关于Window.ShowDialog()方法,有一个常见的容易犯的错误。下面给出这个错误的例子:


DemoA:错误的例子


1. 在WPF项目中,创建一个Windows:DialogWindow


DialogWindow.xaml

<Window x:Class="DemoA.DialogWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="I am a dialog window" Height="200" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="140" />
            <RowDefinition Height="60" />
        </Grid.RowDefinitions>
        
        <Label Grid.Row="0" Margin="12" Content="Hello!" />
        <WrapPanel Grid.Row="1" Margin="0" HorizontalAlignment="Center">
            <Button Content="OK" Margin="5,0,5,0" Width="60" />
            <Button Content="Cancel" Margin="5,0,5,0" Width="60"
                    Click="ButtonCancelOnClick"/>
        </WrapPanel>
    </Grid>
</Window>

DialogWindow.xaml.cs

using System.Windows;

namespace DemoA
{
    /// <summary>
    /// Interaction logic for DialogWindow.xaml
    /// </summary>
    public partial class DialogWindow : Window
    {
        public DialogWindow()
        {
            InitializeComponent();
        }

        private void ButtonCancelOnClick(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
}

然后在MainWindow里面去调用它:

MainWindow.xaml

<Window x:Class="DemoA.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Width="Auto" Height="Auto" Content="Show dialog" Click="ButtonClick" />
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;

namespace DemoA
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private DialogWindow dialogWindow = new DialogWindow();

        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void ButtonClick(object sender, RoutedEventArgs e)
        {
            dialogWindow.ShowDialog();
        }
    }
}

这个例子似乎非常寻常。看出它有什么问题了吗?如果您看出问题来了,那么本文对您来说纯属浪费时间,请移步其它文章,谢谢。


好,下面我们运行它。运行时,点击MainWindow窗口的按钮,第一次点击,弹出了DialogWindow对话框,没什么问题。点击“Cancel”按钮关闭DialogWindow对话框,再次点击MainWindow窗口的按钮,这时候问题出现了,抛出了以下异常:




An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll

Additional information: Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.


如何解决这个问题呢?解决方案如下:DemoB


DialogWindow.xaml.cs

using System.Windows;

namespace DemoB
{
    /// <summary>
    /// Interaction logic for DialogWindow.xaml
    /// </summary>
    public partial class DialogWindow : Window
    {
        private static DialogWindow staticInstance = null;

        public DialogWindow()
        {
            this.InitializeComponent();
            this.Closed += WindowOnClosed;
        }

        public static DialogWindow GetInstance()
        {
            if (staticInstance == null)
            {
                staticInstance = new DialogWindow();
            }

            return staticInstance;
        }

        private void ButtonCancelOnClick(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void WindowOnClosed(object sender, System.EventArgs e)
        {
            staticInstance = null;
        }
    }
}

MainWindow.xaml.cs

using System.Windows;

namespace DemoB
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void ButtonClick(object sender, RoutedEventArgs e)
        {
            DialogWindow.GetInstance().ShowDialog();
        }
    }
}


这样,每次调用Window.ShowDialog()方法的时候,都创建了一个新的DialogWindow实例,所以问题得以解决。




参考:

同样的疑问,在StackOverflow上的讨论如下:

《WPF: Cannot reuse window after it has been closed》

http://stackoverflow.com/questions/3568233/wpf-cannot-reuse-window-after-it-has-been-closed



  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值