Wpf 在窗口之前显示进度条。Show()
当窗口加载时,我无法显示进度条。 事实上,我在datagrid中有一个包含很多项的窗口。 当我调用window.Show()时,它需要很长时间才能打开,所以我想知道,是否可以调用如下内容:Wpf 在窗口之前显示进度条。Show(),wpf,progress-bar,Wpf,Progress Bar,当窗口加载时,我无法显示进度条。 事实上,我在datagrid中有一个包含很多项的窗口。 当我调用window.Show()时,它需要很长时间才能打开,所以我想知道,是否可以调用如下内容: ShowProgressBar spb = new ShowProgressBar(); spb.Topmost = true; spb.Owner = this.Owner; spb.Show(); whil
ShowProgressBar spb = new ShowProgressBar();
spb.Topmost = true;
spb.Owner = this.Owner;
spb.Show();
while(mainWin.isLoaded)
spb.updatePB(); // this method updating progressbar.value.
mainWindow.Show();
但它根本不显示Progresbar,在加载时,只在窗口已满时显示
有什么有用的代码吗?;) 您的问题是它们都在UI线程上,因此在完成加载主窗口之前,您无法更新进度条的UI。解决方案是使用另一个线程更新ProgressBar的UI 像这样的方法应该会奏效:
Dispatcher progressDisptacher;
var uiThread = new Thread(() =>
{
ShowProgressBar spb = new ShowProgressBar();
spb.Topmost = true;
spb.Show();
progressDisptacher = spb.Dispatcher;
// allowing the main UI thread to proceed
System.Windows.Threading.Dispatcher.Run();
});
uiThread.SetApartmentState(ApartmentState.STA);
uiThread.IsBackground = true;
uiThread.Start();
mainWindow.Show();
progressDisptacher.BeginInvokeShutdown(DispatcherPriority.Send);
如您所见,在主窗口加载后,您可以使用以下方法终止进度条线程:
progressDispatcher.BeginInvokeShutdown(DispatcherPriority.Send)代码>我假设您希望在主窗口未加载时更新进度条。所以首先你应该想反转while循环
然而,这一个问题要微妙一些
欢迎来到非常痛苦的STA线程工作。一个快速的经验法则是,任何和您在屏幕上看到的内容有关的事情都必须通过主线程来完成。事实上,当您不使用主线程时,会发生很多情况,.net使用它重新绘制任何已更改的内容(如进度条)
为了能够显示进度条,您必须将UI线程的控制权返回到所谓的消息循环。最简单的方法是返回方法调用。但在此之前,您需要设置一个计时器来定期检查进度
您当前的代码会花一整天的时间检查主窗口是否已加载,而不是实际加载主窗口
然而,主窗口的实际加载可能再次需要使用主线程来构造
Soooo…最后,您应该同步将项目加载到数据网格中的绑定。while循环是反向的。如果开始时未加载,它将跳过ui更新,如果开始时未加载,它将继续尝试使用“我已完成”更新ui虽然理论上这会起作用,但实际上并不能解决实际的根本原因,也就是说,OP没有将UI线程视为宝贵的资源,而是异步运行IO系统。此外,您还需要解释,您需要使用新的Dispatcher/线程更新ProgressBar。尽管您可以在模型中的进度属性上使用INPC,“加载”屏幕是一个非常常见的请求,它通过允许另一个线程在另一个线程真正加载时显示等待屏幕来解决阻塞UI线程的根本原因。因为你不知道他有什么是他的表单的初始化,如果他可以将东西移动到异步状态,你的答案不会以任何方式帮助OP解决他的问题。。。(但这是对问题的一个很好的解释。)关于更新进度条,一个简单的动画就足够了,这样他甚至不需要实现INotifyPropertyChanged……好的,实际上它工作得很好。现在更新progressbar有问题了——我想我不能在uiThread处于活动状态时更新它,但我该怎么做呢?当我试着像我上面写的那样做的时候,得到了另一个进程拥有它的错误,你的意思是我在datagrid中加载项时需要更新progressBar?但是,当我在整个应用程序中也有很多数据网格时,我想创建一个类,它将在每个窗口中打开,不管是否有数据网格?我最喜欢的是公共可用方法,我可以在应用程序中的任何地方运行;)一个从事我正在从事的项目的承包商的想法与你的想法类似。结果是一个单例进度条。现在,进度条占用了UI线程,所以任何时候加载任何东西,用户都不能做任何事情,甚至不能将窗口移开。由于不同装载机之间的竞争条件,它也会随机崩溃。现在,我的观点是。仅在严格必要时使用UI线程以避免UI锁定。加载通知应该是上下文的,如果加载网格a和b,我希望在加载网格a后立即使用网格a,而不是在加载b后。在加载数据时尝试“修饰”相关网格。首先,我想尝试Blachshma答案,但仍然无法更新progressBar值(例如,是progressBar.value++),不确定在哪里(在循环或其他)我应该更新它吗..也许你是对的-嗯,我有很多窗口,但只在几个地方需要它,那里有很多项目要加载,所以我们会看到;)请参考其他答案的评论。此外,您不应该使用循环,而应该使用计时器。同样,这是因为循环不会返回对UI线程的控制以实际执行重画。