繁体   English   中英

BackgroundWorker:在用户控件之间切换后,在完成事件中启用/禁用按钮不起作用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM