为什么BackgroundWorker_RunWorkerCompleted不更新GUI?

lak*_*kai 5 c# wpf backgroundworker

我已经搜索了论坛,但没有问我的问题是否符合我的问题...

我使用BackgroundWorker来处理非常耗时的操作.完成此操作后,应将按钮设置为启用,以便用户可以执行其他操作.

我正在使用WPF并且我正在遵循MVVM模式,因此我无法直接访问此按钮.我必须在BackgroundWorker_RunWorkerCompleted事件处理程序中调用一个方法,该方法将表示按钮enabled-state的Property设置为true.

这一切都很好,除了一件事:按钮只在我点击进入窗口(或最大化窗口,...)后重新绘制.多数民众赞成非常烦人,并花了我一整天摆脱这种行为,但我找不到解决方案......

BackgroundWorker_RunWorkerCompleted事件处理程序如下所示:

    void fileLoadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        SetButtonToEnabled(); }
Run Code Online (Sandbox Code Playgroud)

有谁知道如何解决这个问题?

编辑:

该按钮绑定到一个命令:

<Button Name="btnLoadTargetFile" Command="{Binding Path=LoadTargetCommand}" .../>
Run Code Online (Sandbox Code Playgroud)

这个命令是史密斯在他的博客(http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)中所说的RelayCommand ,看起来像这样:

public RelayCommand LoadTargetCommand
    {
        get
        {
            if (loadTargetCommand == null)
            {
                loadTargetCommand = new RelayCommand(param => this.OnRequestLoadFile(BusinessLogic.CustomTypes.TreeType.Target), param => this.CanLoadTarget);
            }
            return loadTargetCommand;
        }
        set { loadTargetCommand = value; }
    }
Run Code Online (Sandbox Code Playgroud)

this.CanLoadTarget由SetButtonToEnabled()设置为true; 方法

编辑2:

以下代码'有效':

fileLoadBackgroundWorker.RunWorkerAsync(argumentList);
while(fileLoadBackgroundWorker.IsBusy)
  System.Windows.Forms.Application.DoEvents();
SetButtonToEnabled();
Run Code Online (Sandbox Code Playgroud)

但这是一些非常危险和丑陋的代码......

SwD*_*n81 2

虽然它不能解释你的问题,但你可以尝试添加

System.Windows.Forms.Application.DoEvents();
Run Code Online (Sandbox Code Playgroud)

或者

Dispatcher.Invoke(new Action(delegate { }), DispatcherPriority.Background);
Run Code Online (Sandbox Code Playgroud)

到 SetButtonToEnabled 函数调用结束时(在将按钮 Enabled 设置为 true 后)。看起来后台工作人员正在调用 Complete 事件,但 GUI 没有刷新。

下面是在 WPF 中使用后台工作程序的完整示例。您可能想看一下并确保您的东西看起来相同。

您还可以查看使用后台工作对象的异步线程。这是使用调度程序和后台工作人员的一个很好的示例

WPF 线程模型是另一个值得查看的重要来源。