Click here to Skip to main content
15,881,089 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to pass a User between two ViewModels. To do this I am using the MVVM light Messenger framework. Even though a breakpoint is hit where I try to action the model that is passed to the second ViewModel, some TextBlocks that are bound to properties are not updated.

What I have tried:

Here is how I pass the 'User' when someone clicks a login button:

#region Login
private DelegateCommand _loginCommand;
public ICommand LoginCommand
{
    get
    {
        _loginCommand = new DelegateCommand(param => Login());
        return _loginCommand;
    }
}

private async void Login()
{
    var waitWindow = new PleaseWaitWindow();
    waitWindow.Show();

    if (await LoginCheck())
    {
        // TODO: Navigate to the DashboardView
        Messenger.Default.Send(new ChangePage(typeof(DashboardViewModel)));
        Messenger.Default.Send(_chosenUser);
    }

    waitWindow.Close();
}
#endregion


Here is how I subscribe to that message and use its contents:

public DashboardViewModel()
{
    Messenger.Default.Register<User>(this, OnUserReceived);
    Messenger.Default.Register<ChangePage>(this, ChangePage); // Register to Messenger to change Views hosted in ContentControl
}

private void OnUserReceived(User user)
{
    FirstName = user.FirstName; // Breakpoint is hit here with correct value
    LastName = user.LastName;
}


And the two TextBlocks that are bound to the FirstName and LastName properties..:

<StackPanel VerticalAlignment="Center" Margin="5">
    <TextBlock Text="{Binding FirstName}" Foreground="White" Margin="5" FontSize="18"/>
    <TextBlock Text="{Binding LastName}" Foreground="White" FontWeight="Bold" Margin="5" FontSize="20"/>
</StackPanel>


If I set a breakpoint where I action the Messenger then FirstName and LastName are set to the correct values. However, the TextBlocks are not updated and their text remains null.

I have implemented a test button on the DashboardView that simply sets FirstName ="Test"; and this does update the TextBlock to say Text so I am confused as to why passing in a type of User and using its FirstName and LastName doesn't work.

EDIT:

private void OnUserReceived(User user)
{
    Application.Current.Dispatcher.Invoke(() =>
    {
        FirstName = user.FirstName;
        LastName = user.LastName;
    });
}
Posted
Updated 16-Jul-17 21:22pm
v2

1 solution

This behaviour is quite normal,
as the messenger is on a different thread.

I also had this phenomenon once.

You should use a dispatcher:

Application.Current.Dispatcher.Invoke(() =>
{
    FirstName = user.FirstName; // Breakpoint is hit here with correct value
    LastName = user.LastName;
});
 
Share this answer
 
v3
Comments
DRD94 17-Jul-17 3:24am    
Thanks for your time. I've updated my answer to reflect on adding in a dispatcher, however unfortunately the TextBlocks are still not updating, frustrating really. I've even added in a Button that is bound to a command that sets FirstName = "Test". This does actually update the TextBlock so I can only see the problem is with the messenger.
TheRealSteveJudge 17-Jul-17 3:58am    
No problem.
You set the foreground colour to 'White'.
What happens if you set it to e.g. black?
DRD94 17-Jul-17 4:06am    
I have a black background hence the white. I changed it to red and no luck still. If I set the button to something like MessageBox.Show(FirstName);, so that is after FirstName should be set to the passed value it just shows null. It seems to me that FirstName is being set where the breakpoint is being hit but then being wiped again for some reason.
TheRealSteveJudge 17-Jul-17 4:15am    
OK. I thought maybe the background was white as well.
What do you see when using the debugger at the first line of the OnUserReceived method? How often is the breakpoint hit after logging in?
DRD94 17-Jul-17 4:29am    
Pretty confused now. The breakpoint is only hit once and FirstName/LastName are set correctly. If I add in a MessageBox to the end of the OnUserReceived method and follow through the debugger, it looks like the ViewModel is initialised before the View. Is there a way I can check the View (and its TextBlocks) are initialised before the ViewModel? Maybe the sending of the ViewModel to change ViewModels is messing this up?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900