简体   繁体   中英

MVVM Light and multiple instances of the same ViewModel, not updating UI

Been using MVVM Light for a while now so I do have a little experience, however I have never tried doing multiple instances of the same viewmodel

Basically, I have created a usercontrol which has a viewmodel and I am using 4 instances of this control in a WPF window.

Here is how I do the binding in xaml, pretty simple stuff.

<UserControl.DataContext>
   <Binding Path="PodView" Source="{StaticResource Locator}"/>
</UserControl.DataContext>

<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="6,0,0,0" Text="{Binding PodModel}"/>

Here is the service locator code.

public class ViewModelLocator
{
    /// <summary>
    /// Initializes a new instance of the ViewModelLocator class.
    /// </summary>
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<PODViewModel>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }

    public PODViewModel PodView
    {
        get
        {
            //return ServiceLocator.Current.GetInstance<PODViewModel>(Guid.NewGuid().ToString());
            return new PODViewModel();
        }
    }

    public static void Cleanup()
    {
        // TODO Clear the ViewModels
    }
}

As you can see I have tried a few ways of returning an instance of the viewmodel but I don't think the problem is there.

Ok so now onto the issue. In the viewmodel I have a property like this which is bound to a textbox

private string _PodModel;
public string PodModel
{
    get { return _PodModel; }
    set
    {
        if (_PodModel != value)
        {
            _PodModel = value;
             RaisePropertyChanged(() => PodModel);
        }
    }
}

Now in the constructor I have this which works fine and I verify this in both blend and when the programme is running.

public PODViewModel()
{
    if (IsInDesignMode)
    {
        ////    // Code runs in Blend --> create design time data.                
        PodModel = "HSA3";    // <-- This works fine
    }
    else
    {
        ////    // Code runs "for real"                
        PodModel = "Fred";    // <-- This works fine
    }
}

Now the problem is that each control has a thread for doing a long task and it changes the PodModel property. I don't get any exceptions when doing this but the UI does not update.

PodModel = "blah blah blah";

So I moved the code onto the UI thread like so but the UI still won't update.

DispatcherHelper.CheckBeginInvokeOnUI(() =>
   {
       PodModel = "blah blah blah";
   });

I have put a breakpoint on the property 'set' and I can see the property does change as it should.

Any ideas why the UI won't update?

Update 1: I have noticed that there are 2 calls to getting the instance of the PodViewModel

I think that the problem is that PodView property always returns a new object. It leads to the situation in which a different instance of a view model is being updated (for example by setting PodModel property to "blah blah blah" ) than UI is bound to. It cannot work because UI doesn't know that his instance of view model was updated. To confirm this try to use the following code:

private PODViewModel  _podView = new PODViewModel();  
public PODViewModel PodView
{
    get
    {
        return _podView ;
    }
}

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