Search code examples
c#wpfmvvm.net-3.5dispatcher

TargetParameterCountException: the parameter count mismatch


Below my view model and data model from my WPF MVVM app. I am having problems when performing the invoke (see below), the exception parameter count mismatch is thrown. The method "getDataFromDatabase" is returning a collection of "UserData". So how to solve this?

View Model:

public class MyViewModel : BaseViewModel
{
    private static Dispatcher _dispatcher;
    public ObservableCollection<UserData> lstUsers

    public ObservableCollection<UserData> LstUsers
    {
        get
        {
            return this.lstUsers;
        }

        private set
        {
            this.lstUsers= value;
            OnPropertyChanged("LstUsers");
        }
    }

    // LoadData is called from the constructor of the view code-behind (xaml.cs) once DataContext is correctly set.
    public void LoadData()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
        {
            var result = getDataFromDatabase();
            UIThread((p) => LstUsers = result);
        }));
    }

    ObservableCollection<UserData> getDataFromDatabase()
    {            
        return this.RequestDataToDatabase();
    }

    static void UIThread(Action<object> a)
    {
        if(_dispatcher == null) 
        {
           _dispatcher = Dispatcher.CurrentDispatcher;
        }

        _dispatcher.Invoke(a); <---- HERE EXCEPTION IS THROWN
    }
}

Data Model:

public class UserData
{
   public string ID{ get; set; }
   public string Name { get; set; }
   public string Surname { get; set; }

   // Other properties
}

Solution

  • An Action<object> is an Action with a parameter of type object. It would have to be invoked via the Invoke(Delegate method, params object[] args) overload with a single parameter:

    Application.Current.Dispatcher.Invoke(a, someObject);
    

    So change Action<object> to Action:

    static void UIThread(Action a)
    {
        Application.Current.Dispatcher.Invoke(a);
    }
    

    and call it like this:

    UIThread(() => LstUsers = result);
    

    You may also want to make your LoadData method async and write it like this:

    public async Task LoadData()
    {
        await Task.Run(() =>
        {
            var result = getDataFromDatabase();
            Application.Current.Dispatcher.Invoke(() => LstUsers = result);
        });
    }