更新:2018 2. 27

这是我两年前写的文章,当时没考虑到debug环境下的问题,事实上debug环境下才会有AdornerLayer,这个问题应该不是单纯由AdornerLayer引起的

刚好今年一月份的时候有个人艾特了我http://bbs.csdn.net/topics/392301858,而我已经很久没写WPF了

请参考提问者最后一个回答:

但网络上也没有别的猜测和处理办法了,只有在窗体里面建立线程句柄 之后 再启动线程。然后 overrides onclosing里面  关掉没退出的线程就可以了。程序可以正常退出。


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

 private void ControlTypeSelectingBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
Type type = ControlTypeSelectingBox.SelectedItem as Type; if (type == null)
throw new ArgumentNullException("Type is null"); ConstructorInfo info = type.GetConstructor(System.Type.EmptyTypes);
Control control = info.Invoke(null) as Control; Window window = control as Window;
Window windowAdnore = null; //注意,下面必须要有打开窗口或者把控件放入grid的操作,这样才能让下面的template正确显示出来
if (window != null)
{
window.WindowState = System.Windows.WindowState.Minimized;
window.ShowInTaskbar = false;
window.Owner = this;
window.Show(); windowAdnore = Application.Current.Windows[Application.Current.Windows.Count - ];
}
else
{
control.Visibility = Visibility.Collapsed;
grid.Children.Add(control);
} ControlTemplate template = control.Template; XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; StringBuilder strbuilder = new StringBuilder();
XmlWriter writer = XmlWriter.Create(strbuilder, settings);
XamlWriter.Save(template, writer); txtTemplateBrowser.Text = strbuilder.ToString(); if (window == null)
grid.Children.Remove(control);
else
{
window.Close();
windowAdnore?.Close();
}
}
catch (Exception ex)
{
txtTemplateBrowser.Text = "<< Error generating template:" + ex.Message + ">>";
}
}

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

 protected override void OnClosed(EventArgs e)
{
var collections = Application.Current.Windows; foreach (Window window in collections)
{
if (window != this)
window.Close();
} base.OnClosed(e);
}

  这样居然能正常退出了!

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

  

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

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

  

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

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

  贴正确关闭的代码:

         private void ControlTypeSelectingBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
Type type = ControlTypeSelectingBox.SelectedItem as Type; if (type == null)
throw new ArgumentNullException("Type is null"); ConstructorInfo info = type.GetConstructor(System.Type.EmptyTypes);
Control control = info.Invoke(null) as Control; Window window = control as Window;
Window windowAdnore = null; //注意,下面必须要有打开窗口或者把控件放入grid的操作,这样才能让下面的template正确显示出来
if (window != null)
{
window.WindowState = System.Windows.WindowState.Minimized;
window.ShowInTaskbar = false;
window.Owner = this;
window.Show(); windowAdnore = Application.Current.Windows[Application.Current.Windows.Count - ];
}
else
{
control.Visibility = Visibility.Collapsed;
grid.Children.Add(control);
} ControlTemplate template = control.Template; XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; StringBuilder strbuilder = new StringBuilder();
XmlWriter writer = XmlWriter.Create(strbuilder, settings);
XamlWriter.Save(template, writer); txtTemplateBrowser.Text = strbuilder.ToString(); if (window == null)
grid.Children.Remove(control);
else
{
window.Close();
windowAdnore?.Close();
}
}
catch (Exception ex)
{
txtTemplateBrowser.Text = "<< Error generating template:" + ex.Message + ">>";
}
}

最新文章

  1. 「译」JUnit 5 系列:基础入门
  2. Unity 处理IOC AOP
  3. 【转载学习前辈的经验】-- Mistakes I made (as a developer) 我(作为一名开发者)所犯过的错误
  4. HDU 1251统计难题
  5. net-snmp配置:snmp v3的安全配置
  6. Java容器题库
  7. loj 1002(spfa变形)
  8. Linux系统编程--文件IO操作
  9. [转]去除inline-block元素间间距的N种方法
  10. Android实现接口方式注册监听器
  11. log4net 发布到生产环境不写日志的解决方法--使用 NLog日志
  12. java抽象类与接口 详解
  13. CodeForces 27D - Ring Road 2 构图2-sat..并输出选择方案
  14. WIN下和LINUX动态库的区别
  15. ios 文字图标
  16. google浏览器的安装
  17. gcc编译器优化给我们带来的麻烦???
  18. 查找算法---find运算,find_first_of的使用
  19. iOS开发解决json串中的NSNull类型
  20. 【SSD,FIO,SAS选择的一些小结】SSD,FIO,SAS选择的一些小结

热门文章

  1. c# Using Settings under visual studio 2012
  2. 5805 NanoApe Loves Sequence(想法题)
  3. Linux磁盘分区及配额
  4. 2 django系列之django分页与templatetags
  5. Collection集合的功能及总结
  6. excel批处理_判断一个名称是不是药品
  7. std::unique_lock&lt;std::mutex&gt; or std::lock_guard&lt;std::mutex&gt; C++11 区别
  8. IOS开发遇到(null)与&lt;null&gt;轻松处理
  9. Bubble Cup 8 finals C. Party (575C)
  10. [HttpPost]和[AcceptVerbs(HttpVerbs.Post)]区别