'System.Reflection.TargetInvocationException'(MVVM Light 内部)

'System.Reflection.TargetInvocationException' (Inside MVVM Light)

我使用了 MVVM Light 工具包,当我在 ViewModelLocator 中加载 ViewModel 实例时出现异常 'System.Reflection.TargetInvocationException' 类型的异常发生在 mscorlib.ni.dll 中,但未在用户代码中处理。找了很多都没找到解决办法

我的 ViewModelLocator 代码:

    /*
  In App.xaml:
  <Application.Resources>
      <vm:ViewModelLocator xmlns:vm="clr-namespace:ToDoList"
                           x:Key="Locator" />
  </Application.Resources>

  In the View:
  DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"

  You can also use Blend to do all this with the tool's support.
  See http://www.galasoft.ch/mvvm
*/

using Cimbalino.Phone.Toolkit.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Practices.ServiceLocation;
using System.Windows;

namespace ToDoList.ViewModel
{
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// </summary>
    public class ViewModelLocator
    {
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            ////if (ViewModelBase.IsInDesignModeStatic)
            ////{
            ////    // Create design time view services and models
            ////    SimpleIoc.Default.Register<IDataService, DesignDataService>();
            ////}
            ////else
            ////{
            ////    // Create run time view services and models
            ////    SimpleIoc.Default.Register<IDataService, DataService>();
            ////}

            if (!SimpleIoc.Default.IsRegistered<IMarketplaceReviewService>())
            {
                SimpleIoc.Default.Register<IMarketplaceReviewService, MarketplaceReviewService>();
            }

            SimpleIoc.Default.Register<ToDoViewModel>();
        }

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


        public static void Cleanup()
        {
            // TODO Clear the ViewModels
            var viewModelLocator = (ViewModelLocator)Application.Current.Resources["Locator"];
            viewModelLocator.ToDo.Cleanup();

            Messenger.Reset();
        }
    }
}

我的 ToDoViewModel :

using Cimbalino.Phone.Toolkit.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using ToDoList.Models;

namespace ToDoList.ViewModel
{
   public class ToDoViewModel : ViewModelBase
    {

       private readonly IMarketplaceReviewService _marketplaceReviewService;
       public ICommand DeleteCommand { get; private set; }
       public ICommand AddCommand { get;  set; }
       public ICommand RateCommand { get; private set; }
       public string Text { get;  set; }

        // LINQ to SQL data context for the local database.
        private ToDoDataContext toDoDB;

        // Class constructor, create the data context object.
        public ToDoViewModel(string toDoDBConnectionString, IMarketplaceReviewService marketplaceReviewService)
        {


            _marketplaceReviewService = marketplaceReviewService;
            toDoDB = new ToDoDataContext(toDoDBConnectionString);
            DeleteCommand = new RelayCommand<ToDoItem>(DeleteToDoItem);
            AddCommand = new RelayCommand(Add);
            LoadCollectionsFromDatabase();
            RateCommand = new RelayCommand(Rate);

        }

        private void Rate()
        {
            _marketplaceReviewService.Show();
        }
        private void Delete(ToDoItem newToDoItem)
        {
            //ToDoItem newToDoItem = obj as ToDoItem;

            DeleteToDoItem(newToDoItem);
        }

        private void Add()
        {
          ToDoItem newToDoItem = new ToDoItem
          {
              ItemName = this.Text,

          };
          AddToDoItem(newToDoItem);
        }

        //
        // TODO: Add collections, list, and methods here.
        //

        // Write changes in the data context to the database.
        public void SaveChangesToDB()
        {
            toDoDB.SubmitChanges();
        }


        // All to-do items.
        private ObservableCollection<ToDoItem> _allToDoItems;
        public ObservableCollection<ToDoItem> AllToDoItems
        {
            get { return _allToDoItems; }
            set
            {
                _allToDoItems = value;
                NotifyPropertyChanged("AllToDoItems");
            }
        }




        public void LoadCollectionsFromDatabase()
        {

            // Specify the query for all to-do items in the database.
            var toDoItemsInDB = from ToDoItem todo in toDoDB.Items
                                select todo;

            // Query the database and load all to-do items.
            AllToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);

            // Specify the query for all categories in the database.






        }
        // Add a to-do item to the database and collections.
        public void AddToDoItem(ToDoItem newToDoItem)
        {
            // Add a to-do item to the data context.
            toDoDB.Items.InsertOnSubmit(newToDoItem);

            // Save changes to the database.
            toDoDB.SubmitChanges();

            // Add a to-do item to the "all" observable collection.
            AllToDoItems.Add(newToDoItem);


        }
        // Remove a to-do task item from the database and collections.
        public void DeleteToDoItem(ToDoItem toDoForDelete)
        {

            // Remove the to-do item from the "all" observable collection.
            AllToDoItems.Remove(toDoForDelete);

            // Remove the to-do item from the data context.
            toDoDB.Items.DeleteOnSubmit(toDoForDelete);



            // Save changes to the database.
            toDoDB.SubmitChanges();
        }
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        // Used to notify the app that a property has changed.
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }
}

异常发生在

实际上您的 ViewModelLocator 无法创建 ToDoViewmodel 的实例,因为您的 TodoViewmodel 需要两个参数,一个是 IMarketplaceReviewService 类型,另一个 toDoDbConnectionString 的字符串。

注意 :- IMarketplaceReviewService 类型参数来自您已经注册的 ViewmodelLocator 但是您的第二个参数 toDoDbConnectionString 不是来自任何地方所以 ToDoViewModel 没有被实例化。

第一个解决方案:- 这是快速合法的解决方法(因为我不知道您的连接字符串是要更改还是保持不变)。所以像这样更改您的 TodoViewModel 构造函数:-

public ToDoViewModel(IMarketplaceReviewService marketplaceReviewService)
    {
        // Save your connection string somewhere in Constant Class
        // Use that constants directly here.
        _toDoDbConnectionString = "Your Connection string";
        ...
    }

第二个解决方案 :- 您可以创建 Setting - ISetting(Class-Interface) 对并像传递 IMarketplaceReviewService 一样传递它并将其注册到ViewModelLocator.

希望对您有所帮助:)