WPF不正确的方式关闭窗体导致自定义带蒙版的MessageBox弹出后,界面无法操作的问题。
这两天在项目中改造了自定义的MessageBox,在MessageBox加入了蒙版,在改造的途中,发现MessageBox弹窗弹出后,整个系统都无法点击了,只能通过任务管理器去关闭窗体了。
刚开始以为MessageBox的蒙版代码有问题,不停的修改,最后还是一模一样的结果。于是试着新建了一个全新的项目,用相同的蒙版代码,发现一切正常。
于是一句一句代码的删除调试我的项目。最终终于找到了问题的所在。
这句“问题”代码就出现在App.xaml代码中,App.xaml逻辑是:系统启动后加载启动动画,然后线程检查数据是否正常,检查完毕后,关闭动画。打开主窗体。
删除如下这句代码,我的蒙版就正常了,弹出来的窗体可以点击了。
请问是什么情况导致的这样的问题呢?
另外我应该怎么正确的关闭splashScreenWd呢?
//在窗体初始化完毕后,关闭加载动画的窗口
splashScreenWd.Dispatcher.Invoke(new System.Windows.Forms.MethodInvoker(delegate { splashScreenWd.Close(); }));
App.xaml代码如下。
Window openWindow = null;
SplashScreenWd splashScreenWd = null;
protected override void OnStartup(StartupEventArgs e)
{
#region 打开启动动画
Thread thread = new Thread(() =>
{
splashScreenWd = new SplashScreenWd("正在初始化系统", new SolidColorBrush(Colors.Gainsboro));
splashScreenWd.ShowDialog();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
#endregion
RefObj refObj = new RefObj();
Service service = null;
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, ee) =>
{
#region 检查系统更新
SystemMethod systemMethod = new SystemMethod();
List<string> updateFiles = systemMethod.GetSysUpdateFiles();
#region 强制更新系统,更新文件丢失则无法使用系统
if (updateFiles.Count > 0)
{
string VersionNo = systemMethod.GetSysVersionNo();
this.Dispatcher.BeginInvoke((Action)delegate
{
if (File.Exists("Startup.exe"))
{
new ShowUpdateInfoWd(null, String.Format("\n检测到新版本:{0}", VersionNo)).ShowDialog();
Process.Start("Startup.exe");
}
else new ShowMessageWd(null, "\n" + "检测到新版本,但更新文件Startup.exe丢失").ShowDialog();
Environment.Exit(0);
return;
});
}
#endregion
#endregion
#region 查询该设备是否有效
refObj = systemMethod.GetDeviceInfo();
#endregion
};
worker.RunWorkerCompleted += (s, ee) =>
{
#region 系统检查,系统缓存完毕,打开主窗体
openWindow = refObj.IsSuccess ?
openWindow = new MainWd(service) :
openWindow = new ShowMessageWd(refObj.ExecuteNum > 0 ? service : null, refObj.Message);
openWindow.Show();
#region 窗体初始化完毕
openWindow.ContentRendered += (ss, ev) =>
{
//在窗体初始化完毕后,关闭加载动画的窗口
splashScreenWd.Dispatcher.Invoke(new System.Windows.Forms.MethodInvoker(delegate { splashScreenWd.Close(); }));
IntPtr handle = new WindowInteropHelper(openWindow).Handle;
SetForegroundWindow(handle);
};
#endregion
#endregion
worker.Dispose();
};
worker.RunWorkerAsync();
}