首页 > 代码库 > WPF直接用Window.Close直接关闭窗口导致不能完全退出的问题
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 }
WPF直接用Window.Close直接关闭窗口导致不能完全退出的问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。