1

I'm trying to put an universal app together and I'm using mvvm light but I'm getting the following error when compiling my app:

Error   1   Type not found in cache: MyApp.Model.LocationModel
...\MyApp.WindowsPhone\Views\LocationPage.xaml  10  5   MyApp.WindowsPhone

It does compile successfully but I can't figure out what's causing the problem. I've found a couple of article on stackoverflow:

SimpleIoC - Type not found in cache: Windows.UI.Xaml.Controls.Frame

MVVM Light “Type Not Found in cache”

But neither one apply to my problem. The first thing I've noticed is that the error is somehow displaying a Model where the problem resides rather than a ViewModel.

Error   1   Type not found in cache: MyApp.Model.LocationModel. 
...\MyApp\MyApp.WindowsPhone\Views\LocationPage.xaml    10  5   MyApp.WindowsPhone

The error in my xaml occurs on the line where I defined my DataContext:

<Page
....
DataContext="{Binding Source={StaticResource Locator}, Path=LocationViewModel}">

My LocationViewModel class is defined as follows:

public class LocationViewModel : ViewModelBase
{
    private RelayCommand _saveCommand;
    private RelayCommand _cancelCommand;

    #region Properties

    public int Id
    {
        get
        {
            return this.Location.Id;
        }
    }

    public string Title
    {
        get
        {
            return this.Location.Title;
        }
    }

    public string Description
    {
        get
        {
            return this.Location.Description;
        }
    }

    public string CreatedDateFormatted
    {
        get
        {
            return this.Location.CreatedDate.ToString("d");
        }
    }

    public string LastUpdatedDateFormatted
    {
        get
        {
            return Location.LastUpdatedDate.ToString("d");
        }
    }

    public string ImagePath
    {
        get
        {
            return this.Location.ImagePath;
        }
    }

    public LocationModel Location
    {
        get;
        private set;
    }

    #endregion

    #region Constructors

    public LocationViewModel(LocationModel model)
    {
        this.Location = model;
        this.Location.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == LocationModel.DescriptionPropertyName)
                {
                    RaisePropertyChanged(() => Description);
                }
                if (e.PropertyName == LocationModel.TitlePropertyName)
                {
                    RaisePropertyChanged(() => Title);
                }
                if (e.PropertyName == LocationModel.ImagePathPropertyName)
                {
                    RaisePropertyChanged(() => ImagePath);
                }
                if (e.PropertyName == LocationModel.CreatedDateStringPropertyName)
                {
                    RaisePropertyChanged(() => CreatedDateFormatted);
                }
                if (e.PropertyName == LocationModel.LastUpdatedDateStringPropertyName)
                {
                    RaisePropertyChanged(() => LastUpdatedDateFormatted);
                }
            };
    }

    #endregion

    public RelayCommand SaveCommand
    {
        get
        {
            return this._saveCommand ?? (this._saveCommand = new RelayCommand(ExecuteSaveCommand));
        }
    }

    public RelayCommand CancelCommand
    {
        get
        {
            return this._cancelCommand ?? (this._cancelCommand = new RelayCommand(ExecuteCancelCommand));
        }
    }


    private void ExecuteSaveCommand()
    {

    }

    private void ExecuteCancelCommand()
    {

    }
}

and my property for my LocationViewModel is defined as follows in my ViewModelLocator class:

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

and is registered in the ViewModelLocator's constructor:

SimpleIoc.Default.Register<LocationViewModel>();

and when this code is called, it registers my LocationViewModel correctly.

When click on my "add" button, it navigate to the page where the LocationViewModel is set as the DataContext and the error occurs at run-time.

The code I'm calling from LocationsViewModel (not LocationViewModel) that's calling the navigation is:

    private void ExecuteAddCommand()
    {
        _navigationService.Navigate(typeof(LocationPage));
    }

When debugging the above, it creates the LocationPage, followed by calling the LocationViewModel from the ViewModelLocator and this is when the same error occurs but at run-time i.e.

return ServiceLocator.Current.GetInstance<LocationViewModel>();

When I move my mouse over the , it displays the following:

Message: "Type not found in cache: MyApp.Model.LocationModel."
InnerException: at GalaSoft.MvvmLight.Ioc.SimpleIoc.DoGetService
(Type serviceType, String key) at 
GalaSoft.MvvmLight.Ioc.SimpleIoc.GetInstance[TService]()
at Inventory.ViewModel.ViewModelLocator.get_LocationViewModel()

Actually, I've just realized that the error is generated much earlier but no error is thrown. It is actually generated when registering the LocationViewModel in the constructor of ViewModelLocator:

SimpleIoc.Default.Register<LocationViewModel>();

Any ideas?

Thanks.

Community
  • 1
  • 1
Thierry
  • 6,142
  • 13
  • 66
  • 117

3 Answers3

0

The LocationViewModel constructor has dependency on LocationModel. The SimpleIoc container couldn't create the view model instance as the constructor requires a LocationModel object which you can't pass directly. You can probably use MVVMLight Messenger to decouple the LocationModel object from the LocationViewModel constructor.

public LocationViewModel()
{
    MessengerInstance.Register<LocationModel>(this,m=>{model=m;
            //PropertyChanged code
    });
}

In the LocationsViewModel, send the LocationModel object you wanted to use in the LocationViewModel constructor by just sending it.

public void ExecuteAddCommand()
{
   MessengerInstance.Send<LocationModel>(LocationModelObj);
   _navigationService.navigate(tyepof(LocationPage));
}

For this to succeed though, you'd need to register LocationViewModel to register to receive LocationModel object before sending the object from LocationsViewModel. So, you need to create your view model immediately by using an overload of SimpleIoc's Register method.

SimpleIoc.Default.Register<LocationViewModel>(true);
Sridhar
  • 837
  • 1
  • 10
  • 21
  • I haven't had a chance to try out what you suggested just yet, as it got me thinking and I ended up trying something else based what you mentioned and this also worked. I'm not sure this is the correct solution either, so I will spend a bit more time investigating both solutions and I'll update accordingly once I'm done. – Thierry Dec 31 '14 at 01:17
0

Based on what @Shridhar said The SimpleIoc container couldn't create the view model instance as the constructor requires a LocationModel object which you can't pass directly, I thought I'd try adding a parameterless constructor but I got another error i.e.

Cannot register: Multiple constructors found in LocationViewModel but none marked with PreferredConstructor.

So I marked my parameterless constructor with the PreferredConstructor as such:

    [PreferredConstructor]
    public LocationViewModel()
    {

    }

This sorted my problem but as mentioned to @Shridar, I'm not sure whether or not this is the correct solution so I will spend more time investigating and see if this works as expected and doesn't have any side effects.

I'll update as soon as I have something.

usefulBee
  • 9,250
  • 10
  • 51
  • 89
Thierry
  • 6,142
  • 13
  • 66
  • 117
0

I also experienced a similar error while trying to use MVVMLight DialogService; the solution was to make sure it is registered in the ViewModelLocator

public ViewModelLocator()
{
  SimpleIoc.Default.Register<IDialogService, DialogService>();
}
usefulBee
  • 9,250
  • 10
  • 51
  • 89