標籤: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直接關閉視窗導致不能完全退出的問題