Constructor in ViewModel

Is it possible to have a constructor in the ViewModel that initializes the data service?

My data service accesses the data warehouse web service as follows:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using Cirrious.MvvmCross.ViewModels; using Cirrious.MvvmCross.Commands; using MobSales.Logic.DataService; using MobSales.Logic.Base; using MobSales.Logic.Model; namespace MobSales.Logic.ViewModels { public class CustomersViewModel:MvxViewModel { ICustomerService custService; public CustomersViewModel(ICustomerService custService) { this.custService = custService; if (custService != null) { custService.LoadCustomerCompleted += new EventHandler<CustomerLoadedEventArgs>(custService_LoadCustomerCompleted); } loadCustomerCommand = new MvxRelayCommand(LoadCustomer); loadCustomerCommand.Execute(); } private ObservableCollection<Customer> customers; public ObservableCollection<Customer> Customers { get { return customers; } set { customers = value; FirePropertyChanged("Customers"); } } private CustomerViewModel customer; public CustomerViewModel Customer { get { return customer; } set { customer = value; FirePropertyChanged("Customer"); } } private MvxRelayCommand loadCustomerCommand; public MvxRelayCommand LoadCustomerCommand { get { return loadCustomerCommand; } } public void LoadCustomer() { custService.LoadCustomer(); } void custService_LoadCustomerCompleted(object sender, CustomerLoadedEventArgs e) { if (e.Error != null) { return; } List<Customer> loadedCustomers = new List<Customer>(); foreach (var cust in e.Customers) { loadedCustomers.Add(new Customer(cust)); } Customers = new ObservableCollection<Customer>(loadedCustomers); } } 

I get an exception, but I see only the following partial description:

Cirrious.MvvmCross.Exceptions.MvxException: Failed to load ViewModel for type MobSales.Logic.ViewModels.CustomersViewModel from locator MvxDefau…

Binding from View to ViewModel is implemented, as I showed in this post: MVVMCross Bindings in Android

Thank!

+4
c # xamarin.android mvvmcross
May 09 '12 at 7:45 a.m.
source share
1 answer

One of the unusual (stubborn) features of MvvmCross is that by default it uses the ViewModel constructor options as part of the navigation mechanism.

This is explained by the example of my answer to Passing variables from ViewModel to another view (MVVMCross)

The basic idea is that when the HomeViewModel requests navigation using:

 private void DoSearch() { RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText }); } 

this will cause the TwitterViewModel to be built using the searchTerm passed to the constructor:

 public TwitterViewModel(string searchTerm) { StartSearch(searchTerm); } 

Currently, this means that each ViewModel must have an open constructor that either has no parameters or only string parameters .

Therefore, the reason your ViewModel does not load is because the MvxDefaultViewModelLocator cannot find a suitable constructor for your ViewModel.




For "services", the MvvmCross structure provides a simple ioc container that can be easily obtained using the GetService<IServiceType>() extension methods. For example, in the Twitter example, one of the ViewModel contains:

 public class TwitterViewModel : MvxViewModel , IMvxServiceConsumer<ITwitterSearchProvider> { public TwitterViewModel(string searchTerm) { StartSearch(searchTerm); } private ITwitterSearchProvider TwitterSearchProvider { get { return this.GetService<ITwitterSearchProvider>(); } } private void StartSearch(string searchTerm) { if (IsSearching) return; IsSearching = true; TwitterSearchProvider.StartAsyncSearch(searchTerm, Success, Error); } // ... } 

Similarly, you can see how conference service data is consumed in Conference BaseViewModel




If you prefer to use some other IoC container or some other mechanism for building your ViewModels, you can override the ViewModel construct in MvvmCross.

Take a look at this question (and answers) for ideas on how to do this - How to replace MvxDefaultViewModelLocator in MVVMCross app

eg. if you want, then it will be pretty easy for you to set up the MyViewModelLocator example in this question to build a ViewModel with your service.

+5
May 9 '12 at 8:32
source share
— -



All Articles