进度栏未在WPF UI上更新

用户2519971

我正在使用下面的代码来显示WPF(MVVM)应用程序中的进度条状态,该应用程序基本上在线程上,但是,如果我使用的是调度程序线程,则其状态不会在UI上更新。

带螺纹:

Main()
    {


      Thread LoadApp = new Thread(MyData);
            LoadApp.Start();
    }

public void MyData()
{
        ProgMessage = "10%";
        ProgValue = 10;
        var varAction = new List<Func<object>>();
        varAction .Add(() => (MainViewMode1)ViewModel1.ViewModel1);
        varAction .Add(() => (MainViewMode2)ViewModel2.ViewModel2);
        varAction .Add(() => (MainViewMode3)ViewModel3.ViewModel3);

        foreach (var action in varAction )
        {
            var obj = action();
            ProgressMessage = // My message from VM
            ProgressBarValue += // My message valuefrom VM;
        }

}

这工作正常,但是因为现在我正在使用依赖项属性,所以遇到了交叉线程异常(STA),因此我将代码更改为:

Main()
{

           Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
            {
               MyData();

            }));

}



 public void MyData()
    {
            ProgMessage = "10%";
            ProgValue = 10;
            var varAction = new List<Func<object>>();
            varAction .Add(() => (MainViewMode1)ViewModel1.ViewModel1);
            varAction .Add(() => (MainViewMode2)ViewModel2.ViewModel2);
            varAction .Add(() => (MainViewMode3)ViewModel3.ViewModel3);

            foreach (var action in varAction )
            {
                var obj = action();
                ProgressMessage = // My message from VM
                ProgressBarValue += // My message valuefrom VM;
            }

   }

现在,我摆脱了线程错误,但是它不更新UI上的进度栏状态吗?

有什么线索吗?

伊恩·格里菲思(Ian Griffiths)

在您放弃对调度程序线程的控制之前,UI元素不会更新。通常,您可以通过返回事件循环来做到这一点,这通常意味着只返回即可。但是,如果您有很多工作要做循环,那么这实际上是不实际的。因此,通常,您不想在UI线程上进行此类工作。

当您说“使用依赖项属性”时,是否表示ViewModel类的属性是依赖项属性?您可能需要重新考虑,因为它阻止了多线程的使用。如果将它们设置为普通的非自动属性,则仍可以使用数据绑定将它们连接到UI。要使UI在属性更改时更新,您需要实现INotifyPropertyChanged,并使属性引发更改通知,然后您将发现可以像第一个示例一样在工作线程上进行工作,并且如果将这些属性绑定到UI,您将不会获得线程异常,并且可以正常更新。

(WPF的数据绑定系统检测UI线程以外的线程上的绑定属性何时发生更改,并自动安排从正确的线程更新UI。但是,如果您想利用此优势,则不能在VM中使用DP。 ,因为DPS具有线程相似性。)

DoEvents其他人提出样式方法确实可以奏效,但这是有问题的,我避免了。它启用了重新进入功能-如果用户与您的应用进行交互而导致事件处理程序运行,则它们将在对的调用中运行Dispatcher.PushFrame这不一定是问题,但是很容易陷入混乱。

还有一种方法是在工作线程上完成工作,但是要使用Dispatcher.Invoke来调用更新ProgressMessageProgressBarValue属性的方法。这样,您的工作就在工作线程上进行(使UI线程可以自由更新),但是您将在UI线程上更新这些DP,从而避免了该错误。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章