Rawukal
Rawukal

Reputation: 65

MvvM Light: Messenger from Event

I'm developing a MvvM - Light based application. In this application i started a async HttpReqest. Then when i got a respond i fire up an event and in this event I'm broadcasting a message to switch to another view. But when I execute this code I got an InvalidOperation Exception: The calling thread cannot access this object because a different thread owns it.

Here is my code:

public class MainLoginViewModel : ViewModelBase
{
    readonly LoginRequest _httpRequest = new LoginRequest();

    public MainLoginViewModel()
    {
        _httpRequest.IsValid += IsUserValid;
    }

    private void ExecuteLoginKeyPressCommand()
    {
        _httpRequest.BeginCheckIfUserIsValid();      
    }

    private static void IsUserValid(object sender, EventArgs e)
    {
        var infoView = new MainInfoView();

        if ((bool)sender)
        {
            infoView.Dispatcher.Invoke(DispatcherPriority.Normal,
                                   new Action(
                                       () => Messenger.Default.Send(infoView, Properties.Resources._mainLoginMessangerToken)));
        }
    } 
}

In this class I'm defining my LoginRequest class which checks if the user is valid. The event is returning a boolean value. If the User is valid i send the new view within the Messenger Class to another ViewModel which handles the Views:

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        SelectedView = new MainLoginView();
        Messenger.Default.Register<MainInfoView>(this, Properties.Resources._mainLoginMessangerToken, PasswordChanged);
    }

    private void PasswordChanged(MainInfoView obj)
    {
        SelectedView = obj;
    }       

    public UserControl SelectedView
    {
        get
        {
            return _selectedViewProperty;
        }

        set
        {
            if (_selectedViewProperty == value)
            {
                return;
            }

            var oldValue = _selectedViewProperty;
            _selectedViewProperty = value;
            RaisePropertyChanged(() => SelectedView, oldValue, value, true);
        }
    }  
}

So do I missunderstand here something? Can anybody help me please?

Greetings

Upvotes: 1

Views: 820

Answers (1)

granaker
granaker

Reputation: 1328

You need to use the dispatcher to update UI elements from a non UI thread. The code that executes when you get the response from your async request isn't on the UI thread.

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(v=vs.95).aspx

Upvotes: 1

Related Questions