ViewModel中的构造函数

是否可以在视图模型中使用构造函数,初始化数据服务? (不要误解我的意思,我的数据服务正在访问数据存储的Web服务)这样的事情(问我因为我得到ViewLoader引发的exception“无法加载ViewModel ……”而且它没有显示整个例外…):

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(custService_LoadCustomerCompleted); } loadCustomerCommand = new MvxRelayCommand(LoadCustomer); loadCustomerCommand.Execute(); } private ObservableCollection customers; public ObservableCollection 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 loadedCustomers = new List(); foreach (var cust in e.Customers) { loadedCustomers.Add(new Customer(cust)); } Customers = new ObservableCollection(loadedCustomers); } } 

完整的例外是:Cirrious.MvvmCross.Exceptions.MvxException:无法从定位器MvxDefau加载类型MobSales.Logic.ViewModels.CustomersViewModel的ViewModel …

从View到ViewModel的绑定实现就像我在这篇文章中发布的那样: Android中的MVVMCross Bindings

谢谢!

MvvmCross的一个不寻常的(固定的)function是默认情况下它使用ViewModel构造函数参数作为导航机制的一部分。

这是我在回答将变量从ViewModel传递到另一个视图(MVVMCross)的一个例子中解释的

基本思想是当HomeViewModel使用以下命令进行导航时:

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

那么这将导致构建TwitterViewModel,并将searchTerm传递给构造函数:

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

目前,这意味着每个ViewModel必须具有公共构造函数,该构造函数没有参数或者只有字符串参数

因此,未加载ViewModel的原因是因为MvxDefaultViewModelLocator无法为ViewModel找到合适的构造函数。


对于“服务”,MvvmCross框架确实提供了一个简单的ioc容器,可以使用GetService()扩展方法轻松访问它。 例如,在Twitter示例中,ViewModel中的一个包含:

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

同样,您可以在Conference BaseViewModel中查看会议服务数据的使用方式


如果您希望使用其他IoC容器或ViewModel的其他构造机制,则可以在MvvmCross中覆盖ViewModel构造。

看一下这个问题(和答案),了解如何做到这一点 – 如何在MVVMCross应用程序中替换MvxDefaultViewModelLocator

例如,如果您愿意,那么您应该很容易调整该问题中的MyViewModelLocator示例,以便使用您的服务构建ViewModel。