[英]BackgroundWorker: Enabling/Disabling Buttons in Completed Event not working after switching between UserControls
我将BackgroundWorker
放在UserControl
遇到问题。 我的WPF应用程序的左侧有一个导航,每个条目都加载自己的UserControl
,用户可以在其中生成PDF文件。
由于创建PDF需要花费一些时间,因此我已经实现了可以完成此工作的BackgroundWorker
,此外,我还禁用了一些按钮并显示进度条。 在RunWorkerCompleted
事件中,我重置了按钮的状态并隐藏了进度条。
尽管有一种情况,所有这些工作都非常好:在PDF创建运行时,用户可以在UserControls之间切换,并且如果他返回开始工作的控件,则控件应显示进度栏和禁用的按钮。 为此,我向UserControl
添加了一个变量(isProcessing)。
控件的构造函数我有这个:
// Check if a current process is running, if so: handle button/progressbar visibility
if (_isProcessing)
{
_stkProgressBar.Visibility = Visibility.Visible;
progressBar1.IsIndeterminate = true;
// Disabling the buttons here is just working with a hack in
// the "Button_IsEnabledChanged" event.
btnDaten.IsEnabled = false;
btnBericht.IsEnabled = false;
this.Cursor = Cursors.Wait;
}
else
{
_stkProgressBar.Visibility = Visibility.Hidden;
}
启用/禁用按钮只是因为这个肮脏的黑客而起作用:
private void btnDaten_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
//HACK: We want to disable the report buttons if a report execution is running.
// Disabling the buttons in the Load Event of the control isn't working
if (_isProcessing && (bool)e.NewValue)
{
btnDaten.IsEnabled = false;
btnBericht.IsEnabled = false;
}
}
现在,如果作业正在运行并且用户在控件之间切换,则处理控件的状态很好。 但是,如果作业结束并且PDF就绪,则无法启用按钮,并且进度条也保持可见。 代码放置在RunWorkerCompleted
事件中:
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// This is not working if the user switches between the controls
_isProcessing = false;
this.Cursor = Cursors.Arrow;
_stkProgressBar.Visibility = Visibility.Hidden;
btnDaten.IsEnabled = true;
btnBericht.IsEnabled = true;
}
我对其进行了调试,发现按钮获得了正确的输入,因此应该将其启用,但是什么也没有发生。 如果用户停留在开始作业的控件中,则按钮和进度栏的状态将正确重置。
是的,这里是用户控件之间的切换。 当您切换并返回时,将创建控件的新实例。 这将创建BackgroundWorker的新实例。 具有不与实际运行的BGW关联的RunWorkerCompleted事件处理程序。
您的代码中还有另一个错误,当原始的BGW实例完成工作并设置(现在不可见)控件属性时,这应该使ObjectDisposedException导致程序崩溃。 您忘了在用户控件之间切换时调用它们的Dispose()。 不太确定如何在WPF中完成此操作,但在winforms中这是无法插拔的漏洞。
只要您要支持切换,就必须对此有所不同。 BGW实例需要与用户控制实例分开,这样它才能在交换机中幸存下来。 相当痛苦的是,在创建和处理控件时,您必须连接和取消连接事件,您肯定需要重写Dispose()方法,并且不要忘记调用它。 如果只允许BGW一次运行一次,则使BGW静态是有道理的。 这应该是正常的。 堆叠用户控件,这样您就只能创建一次,这是一个Q&D修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.