在WPF C#中使用Task.Factory.StartNew时UI不更新按钮

时间:2013-11-14 22:06:52

标签: c# wpf multithreading xaml

WPF / XAML / C#我将进度条的可见性设置为可见,然后在长时间运行的进程后隐藏。我正在尝试使用Task.Factory.StartNew和ContinueWith来完成此任务。这部分工作正常,但是对于某些原因,我的导航按钮数据绑定到命令不会更新,直到我在漫长的过程后实际点击屏幕。如果我省略task.factory.startnew,按钮会正确更新(但我从未看到进度条)。我该如何解决?以下示例代码显示了流程中的问题以及UI中未更新的按钮:

private void DoWorkCommandExecuted()
        {
            //Do stuff
            ShowProgress = Visibility.Visible;

            Task.Factory.StartNew(() =>
                {
                    //Thread.Sleep(3000);
                    for (int i = 0; i < 10000; i++)
                    {
                        s += i.ToString();
                    }

                    ObservableCollection<string> temp = new ObservableCollection<string>();
                    temp.Add("One");
                    temp.Add("Two");
                    temp.Add("Three");
                    temp.Add("Four");
                    temp.Add("Five");

                    BillingCycles = temp;

                    SelectedBillingCycle = BillingCycles[0];
                })
                .ContinueWith(t =>
            {
                ShowProgress = Visibility.Hidden;
            });
        }

启用了控制它的按钮代码的属性样本:

private bool CanFirst
        {
            get
            {
                bool b = false;

                if (BillingCycles != null)
                {
                    if (BillingCycles.Count > 0 && SelectedBillingCycle != BillingCycles[BillingCycles.Count - 1])
                    {
                        b = true;
                    }
                }

                return b;
            }
        }

我正在使用INotifyPropertyChanged。这是一个非常基本的例子来说明我的问题,这是一个更复杂的程序。 “转到第一个”或“转到最后”按钮应根据选择的BillingCycle启用/禁用。如果我不包含在线程中运行的代码,则正确启用/禁用按钮(在进程发生时我无法看到进度条)。

2 个答案:

答案 0 :(得分:1)

我相信它不适合你的原因是CommandManager在后台线程上调用你的命令CanExecute方法而无法从那里更新按钮。操作完成后在UI线程上调用command.RaiseCanExecuteChanged()会导致系统在UI线程上重新评估,因此按钮更新可以正常工作。

答案 1 :(得分:0)

值得检查一下您正在更新通知属性的线程,它应该是indispatcher线程。 如果不是 - 将UpdateSourceTrigger设置为PropertyChanged,绑定应该是双向或单向的。如果有效,请告诉我