WPF直接用Window.Close直接关闭窗口导致不能完全退出的问题

  前几天我在CSDN扔了一个问题,基本描述一下:写了一段这样的代码,来实现获取Control的template,却发现一个这样的问题,就是当我打开了一个window以后,手动调用Close(),窗口的确是消失了,但是当我关闭了主窗口以后,却发现程序没有退出。

 1 private void ControlTypeSelectingBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
 2         {
 3             try
 4             {
 5                 Type type = ControlTypeSelectingBox.SelectedItem as Type;
 6
 7                 if (type == null)
 8                     throw new ArgumentNullException("Type is null");
 9
10                 ConstructorInfo info = type.GetConstructor(System.Type.EmptyTypes);
11                 Control control = info.Invoke(null) as Control;
12
13                 Window window = control as Window;
14                 Window windowAdnore = null;
15
16                 //注意,下面必须要有打开窗口或者把控件放入grid的操作,这样才能让下面的template正确显示出来
17                 if (window != null)
18                 {
19                     window.WindowState = System.Windows.WindowState.Minimized;
20                     window.ShowInTaskbar = false;
21                     window.Owner = this;
22                     window.Show();
23
24                     windowAdnore = Application.Current.Windows[Application.Current.Windows.Count - 1];
25                 }
26                 else
27                 {
28                     control.Visibility = Visibility.Collapsed;
29                     grid.Children.Add(control);
30                 }
31
32                 ControlTemplate template = control.Template;
33
34                 XmlWriterSettings settings = new XmlWriterSettings();
35                 settings.Indent = true;
36
37                 StringBuilder strbuilder = new StringBuilder();
38                 XmlWriter writer = XmlWriter.Create(strbuilder, settings);
39                 XamlWriter.Save(template, writer);
40
41                 txtTemplateBrowser.Text = strbuilder.ToString();
42
43                 if (window == null)
44                     grid.Children.Remove(control);
45                 else
46                 {
47                     window.Close();
48                     windowAdnore?.Close();
49                 }
50             }
51             catch (Exception ex)
52             {
53                 txtTemplateBrowser.Text = "<< Error generating template:" + ex.Message + ">>";
54             }
55         }

  但是如果我不手动调用Close(),而是让window调用Show以后我点窗口上的关闭键,那就可以彻底退出了(手动点击×以后再关闭主窗口程序可以彻底退出了),然后我再在主窗口重写OnClosed方法

 1 protected override void OnClosed(EventArgs e)
 2 {
 3        var collections = Application.Current.Windows;
 4
 5         foreach (Window window in collections)
 6         {
 7                if (window != this)
 8                    window.Close();
 9         }
10
11          base.OnClosed(e);
12 }

  这样居然能正常退出了!

  反正问了好多天没人回答,自己再试了几次,发现原来是这样的:

  

  这是打开窗口并且Show以后Application.Current.Windows集合里面的东西,这下你明白了吧,第一项就是主窗口,第三项就是我们新创建的窗口,那么第二项和第四项是什么东西?

  网上怎么查都查不出这是什么(果然WPF用的人还是比较少呀),去翻了一下MSDN的文档:

  

  想了一下,应该是WPF每次打开窗口的时候,首先打开窗口的实例,如果要Show的时候,那么就加载Window的模板(这也就是为什么Window一定要Show才能看见它的控件模板的原因),并且创建一个不可见的AdornerLayer,当我们手动去关闭Window的时候(按那个关闭按钮),是会关闭掉AdornerLayer的,但是直接Close不会。

  不过这个神奇的坑真的没有人发现过吗?(好奇)

  贴正确关闭的代码:

  

 1         private void ControlTypeSelectingBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
 2         {
 3             try
 4             {
 5                 Type type = ControlTypeSelectingBox.SelectedItem as Type;
 6
 7                 if (type == null)
 8                     throw new ArgumentNullException("Type is null");
 9
10                 ConstructorInfo info = type.GetConstructor(System.Type.EmptyTypes);
11                 Control control = info.Invoke(null) as Control;
12
13                 Window window = control as Window;
14                 Window windowAdnore = null;
15
16                 //注意,下面必须要有打开窗口或者把控件放入grid的操作,这样才能让下面的template正确显示出来
17                 if (window != null)
18                 {
19                     window.WindowState = System.Windows.WindowState.Minimized;
20                     window.ShowInTaskbar = false;
21                     window.Owner = this;
22                     window.Show();
23
24                     windowAdnore = Application.Current.Windows[Application.Current.Windows.Count - 1];
25                 }
26                 else
27                 {
28                     control.Visibility = Visibility.Collapsed;
29                     grid.Children.Add(control);
30                 }
31
32                 ControlTemplate template = control.Template;
33
34                 XmlWriterSettings settings = new XmlWriterSettings();
35                 settings.Indent = true;
36
37                 StringBuilder strbuilder = new StringBuilder();
38                 XmlWriter writer = XmlWriter.Create(strbuilder, settings);
39                 XamlWriter.Save(template, writer);
40
41                 txtTemplateBrowser.Text = strbuilder.ToString();
42
43                 if (window == null)
44                     grid.Children.Remove(control);
45                 else
46                 {
47                     window.Close();
48                     windowAdnore?.Close();
49                 }
50             }
51             catch (Exception ex)
52             {
53                 txtTemplateBrowser.Text = "<< Error generating template:" + ex.Message + ">>";
54             }
55         }
时间: 2024-08-05 08:08:55

WPF直接用Window.Close直接关闭窗口导致不能完全退出的问题的相关文章

WPF学习笔记-如何按ESC关闭窗口

如何按ESC关闭窗口? 在InitializeComponent();下面增加KeyDown事件,如: public ModifyPrice() { InitializeComponent(); this.KeyDown += ModifyPrice_KeyDown; } private void ModifyPrice_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape)//Esc键 { this.Close();

WPF MVVM从入门到精通7:关闭窗口和打开新窗口

原文:WPF MVVM从入门到精通7:关闭窗口和打开新窗口 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WPF MVVM从入门到精通4:命令和事件 WPF MVVM从入门到精通5:PasswordBox的绑定 WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定 WPF MVVM从入门到精通7:关闭窗口和打开新窗口 WPF MVVM从入门到精通8:数据验证 完整示例代码下载Log

自己收藏-javascript用window.open的子窗口关闭自己并且刷新父窗口

function closeMeAndReloadParent() { opener.location.reload(); window.close(); } 一种在父窗口中得知window.open()出的子窗口关闭事件的方法 <HTML><BODY><P> </P><form name=fm_Info><input type=text name=txtValue></form><script language=j

window.opener=null 不需确认就能关闭窗口

在我最近做的项目里有一个小问题.需求上是写生成一条URL可以给用户访问,到达网站特定的内容.并不难.但在访问到的页面上有一个关闭按钮.一按关闭按钮就会出现一个"您所访问的窗口正试图关闭"的确认对话框.在GOOGLE上搜索了一下.看到了这么一行JS代码. window.opener = null; window.close(); 并声称这样就能达到不确认关闭窗口的目的. 解决:window.opener=null;window.close(),只支持IE6不支持IE7的问题? 在wind

关闭窗口(window.close)

close()关闭窗口 用法: window.close(); //关闭本窗口 或 <窗口对象>.close(); //关闭指定的窗口 例如:关闭新建的窗口. <script type="text/javascript"> var mywin=window.open('http://www.imooc.com'); //将新打的窗口对象,存储在变量mywin中 mywin.close(); </script> 注意:上面代码在打开新窗口的同时,关闭该

火狐浏览器中如何使用javascript:window.close()关闭窗口?

代码示例: <input type="button" value="关闭窗体" onclick="javascript:window.close()" /><input type="button" value="打印窗体" onclick="javascript:window.print()" /> 有时候在火狐浏览器使用javascript:window.clo

2.关闭窗口(window.close)

close()关闭窗口 用法: window.close(); //关闭本窗口 或 <窗口对象>.close(); //关闭指定的窗口 例如:关闭新建的窗口. <script type="text/javascript"> var mywin=window.open('http://www.imooc.com'); //将新打的窗口对象,存储在变量mywin中 mywin.close(); </script> 注意:上面代码在打开新窗口的同时,关闭该

让window.close不提示:您查看的网页正在试图关闭窗口。是否关闭此窗口?

正常来说,当我们调用window.close来关闭从地址栏中打开的窗口时,IE会弹出提示说:您查看的网页正在试图关闭窗口,是否关闭此窗口? 你可以将window.close替换成下边的脚本,然后再测试下看: //关闭 $("#close_btn").click(function(){ newwin = window.open("","_parent",""); newwin.close(); }); 是不是没有提示了?猜测原因

【JavaScript】单击网页任意一处打开新窗口与关闭窗口

在一些不正规的网站,尤其是那些挂满广告的下载站,经常在你点击的下载链接之前,无论你点击网页的任何一处都会弹出新窗口. 这样的效果,可以轻松用JavaScript做到,还可以专门指定点击某一区域的Div,才触发打开新窗口的事件. 比如下图的效果: 在原网页中,指定一个Div,无论用户点击这个Div的任意区域,都会打开新窗口,而点击其它地方则不会. 在新窗口的地址栏不可以编辑,不能被调整大小,提供一个"关闭"按钮,关闭该窗口. 原网页的HTML布局如下, <!DOCTYPE HTML