简体   繁体   中英

Using WPF MVVM Light DispatcherHelper

I have a WPF Application in which some controls properties are bound to properties in the relative viewmodel.

Here is the relevant XAML code:

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

This is the DTO:

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

And this is the 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
               }
           });                  
    }

The DispatcherHelper is initialized in App.xaml.cs

When the code executes the lambda in DispatcherHelper.CheckBeginInvokeOnUI I got this exception:

Must create DependencySource on same Thread as the DependencyObject

If I update the _ServiceStatus in the UI thread (as in the constructor of the viewmodel) the ui gets updated.

My question is: isn't DispatcherHelper.CheckBeginInvokeOnUI there to avoid this issue? What am I doing wrong? Thank you!

You should either create the Colore brush on the UI thread or call its Freeze method on the background thread:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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