发现一个.Net中动态加载控件时关于焦点方面的Bug
今天写一个系统框架的时候用到了动态加载,调试的时候发现程序经常会出现死锁的情况,而且死锁的时候还会打开一个“WindowsFormsParkingWindow”后台进程,跑到网上查了半天关于WindowsFormsParkingWindow的资料,结果中文的一篇没找到,蝇文的倒有几篇,对着金山词霸费了九牛二虎之力还没看出个道道来。后来干脆新建了一个项目,只写了几行代码,结果运行的时候发现还是会有死缩的情况:
1、新建一个windows应用程序
2、添加一个UserControl,命名为UserControl1,
3、在UserControl1中添加一个控件,随便什么控件,只要是能获得焦点的都行(Label、Panel等不行)
4、在UserControl1.cs中添加一个方法Test:
public void Test()
{
MessageBox.Show("This is a test!");
}
5、在Form1.cs中添加一个类级变量:private UserControl1 curObj;
6、在Form1中添加一个Panel,命名为Panel1
7、在Form1中添加一个菜单,并添加两个菜单项,命名为menuItemAdd和menuItemMsg;
8、在菜单项menuItemAdd的click事件中添加代码:
panel1.Controls.Clear();
curObj = new UserControl1();
panel1.Controls.Add(curObj);
9、在菜单项menuItemMsg的click事件中添加代码:
if (curObj != null)
curObj.Test();
运行程序,请依次点击menuItemAdd、menuItemMsg、menuItemAdd、menuItemMsg;注意:在这些操作中间不要点击其他地方,发现没有,在第二个MessageBox对话框弹出之后程序死了,用Alt+Tab后发现有一个名为“WindowsFormsParkingWindow”的东西在列表中。
后来发现在第一次点击menuItemMsg弹出对话框之后点一下UserControl1或者在Form1中添加一个可以获得焦点的控件以后程序都不会死,或者在 panel1.Controls.Add(curObj);后面加了一句curObj.Focus();之后问题也可以解决,我想应该是在第二次动态加载的时候由于先把Panel1中的对象销毁了,窗体的也就没有焦点了,在第二次弹出对话框之后,系统找不到当前活动窗体的焦点了,所以程序会死,而当我们鼠标点击一下或者在程序中置一下之后就不会有这样的问题了。
想来想去,问题虽然解决了,总觉得虽然我在写程序的时候的确应该在动态加载对象之后就设焦点,但就算我遗漏了,.Net再怎么说也不应该什么都不处理就让系统死掉还弄个莫名其妙的WindowsFormsParkingWindow吧?至少应该帮我置一下或者抛出一个异常吧?我想这应该算是.Net的一个Bug吧,已经反馈给Microsoft了,见?WishID=25990,希望Microsoft下一个版本能够改掉吧。