WPF直接用Window.Close直接關閉視窗導致不能完全退出的問題

來源:互聯網
上載者:User

標籤:setting   方法   自己   exce   沒有   creat   lan   lte   ted   

  前幾天我在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                 else27                 {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                 else46                 {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                 else27                 {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                 else46                 {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個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.