使用WPF MVVM Light DispatcherHelper

时间:2017-03-10 16:54:44

标签: c# wpf multithreading data-binding mvvm-light

我有一个WPF应用程序,其中一些控件属性绑定到相对viewmodel中的属性。

以下是相关的XAML代码:

[..]
<StackPanel>
    <Ellipse Width="20" Height="20" Fill="{Binding ServiceStatus.Colore}"/>
    <TextBlock Text="{Binding ServiceStatus.Stato}" FontSize="8"></TextBlock>
</StackPanel>
[..]

这是DTO:

public class StatusDTO
{
    public Service.StatoServizio ServiceStatus { get; set; }
    public string Stato { get; set; }
    public SolidColorBrush Colore { get; set; }
}

这是ViewModel:

public class MainViewModel : ViewModelBase
{
    private StatusDTO _ServiceStatus;
    public StatusDTO ServiceStatus 
    {
        get { return _ServiceStatus; }
        set { _ServiceStatus = value; }
    }

    public MainViewModel()
    {   
        [...]         
        _ServiceStatus = new StatusDTO();

        _ServiceStatus.ServiceStatus = SS_UNKNOWN;
        _ServiceStatus.Stato = "INITIALIZING...";
        _ServiceStatus.Colore = new SolidColorBrush(Colors.Gray);

        CheckServiceStatus();
        [...]
    }

    private void CheckServiceStatus()
    {
        ThreadPool.QueueUserWorkItem(o =>
           {
               Service.StatoServizio ss = SS_UNKNOWN;
               while (true)
               {
                   Thread.Sleep(5000);
                   ss = Service.ServiceManager.GetServiceStatus();

                   if (_ServiceStatus.ServiceStatus == ss)
                       continue;

                   _ServiceStatus.ServiceStatus = ss;
                   switch (_ServiceStatus.ServiceStatus)
                   {
                       case SS_STOPPED:
                           _ServiceStatus.Stato = "STOPPED";
                           _ServiceStatus.Colore = new SolidColorBrush(Colors.Red);
                           break;
                      [...]
                   }

                   DispatcherHelper.CheckBeginInvokeOnUI(() => { RaisePropertyChanged("ServiceStatus"); });  <----- HERE I GOT THE EXCEPTION
               }
           });                  
    }

DispatcherHelper在App.xaml.cs

中初始化

当代码在 DispatcherHelper.CheckBeginInvokeOnUI 中执行lambda时,我遇到了这个异常:

Must create DependencySource on same Thread as the DependencyObject

如果我更新UI线程中的_ServiceStatus(如在viewmodel的构造函数中),ui会更新。

我的问题是:isn&#39; DispatcherHelper.CheckBeginInvokeOnUI 有什么可以避免此问题?我究竟做错了什么? 谢谢!

1 个答案:

答案 0 :(得分:3)

你应该在UI线程上创建Colore画笔,或者在后台线程上调用它的Freeze方法:

case SS_STOPPED:
_ServiceStatus.Stato = "STOPPED";
_ServiceStatus.Colore = new SolidColorBrush(Colors.Red);
_ServiceStatus.Colore.Freeze(); // <--
break;
相关问题