如何在Caliburn.Micro中编写/设计Model部件?

时间:2015-06-24 16:57:57

标签: c# mvvm architecture caliburn.micro

我是MVVM模式和Caliburn.Micro的新手。我已经阅读了一些关于如何入门的教程,但我对Caliburn环境中MVVM的Model部分感到困惑。

我想创建我的第一个MVVM应用程序,我有一些设计问题:

  • 在教程中,模型被显示为简单属性 视图模型。我该如何管理更复杂的模型?有没有 命名惯例?显然,应该有一些外部类 为我的模型制作,但我应该如何在我的模型之间进行交流 和视图?
  • 我应该如何保留对一个复杂模型的许多实例的引用? 对于前者cumtomers(客户模型类的实例)

  • 是否有可能操纵一个模型类 的ViewModels?我应该如何存储我的模型参考,所以它将是 从不同的ViewModels可见?

  • 我应该将代码放在更复杂的模型manupulation /文件中, 数据库存储?我该如何调用这样的代码?我不是在这里问 关于SQLConnections,但MVVM最佳实践。 :)

提前感谢您的帮助:)

编辑:--------------------------------------------- ----------

谢谢你的回复。我更清楚地理解这个话题,但我仍然对某些细节感到困惑。

举个例子,让我们假设这个小应用程序。我有一个允许我添加新客户的表单。它有一些字段,如姓名,姓氏等。 按下按钮后,我在ViewModel中调用addCustomer命令。我希望我的程序将新创建的客户存储在数据库中。

我的视图还有List控件(无论如何),它将我的客户显示为原始字符串(例如"姓名:John,Surname:Doe,地址:..."我知道'愚蠢的让它像这样,但我需要一个模型操作的例子(如.toString()))

对于这个例子,我已经创建了一堆东西来说明我对这个过程的看法:

  • 字段 - 它是一组表单字段,如姓名,姓氏等。
  • customerSet - 它是一组Customer类,用于存储所有已创建的 客户
  • .addToDatabase(fields) - 放置新创建的客户的方法 到数据库
  • .getStrings - 一种准备一组字符串的方法 由CustomerView中的列表显示

我认为有两种方法可以解决问题:

  • 第一种方法。我不喜欢这个。唯一的好处是,那 ViewModel处理应用程序内的所有逻辑。分享模式 这将是一个严重的问题,因为保存方法是必然的 ViewModel类。

First Approach

  • 其次,MVC喜欢的方法。对我而言,这是最直观的一个。但是我 我不知道我应该在哪里存储CustomersModel对象,所以很少 ViewModels可以访问它。

Second aproach

哪个更好?或者可能是另一种更适合MVVM的方法?

另一个问题是:我应该在哪里放置将从数据库中加载所有客户的方法,以便它们可以显示在列表中?在" get方法"在viewmodel里面,还是在模型类里面?

1 个答案:

答案 0 :(得分:2)

  

在教程中,模型在ViewModel中显示为简单属性。   我该如何管理更复杂的模型?有没有命名   惯例?显然,应该有一些外部类   我的模型,但我应该如何在我的模型和模型之间进行通信   查看?

您的模型应代表它们所需的任何内容,无论是客户,帐户等。视图模型的工作是处理视图和模型之间的交互。

  

我应该如何保留对一个复杂模型的许多实例的引用?   对于前者cumtomers(Customer模型类的实例)

通常,您会将复杂模型映射到更友好的格式以供显示,您可以手动执行或使用AutoMapper之类的工具。

  

是否有可能操纵一个模型类   的ViewModels?我应该如何存储我的模型参考,以便它可见   来自不同的ViewModels?

如果您正在使用本地数据库,则可以传递ID。如果它是一项服务,您可以在本地保留模型,以供其他视图模型使用。您还可以将单例ISharedData注入需要使用共享数据的视图模型中。

  

我应该将代码放在更复杂的模型manupulation / file中,   数据库存储?我该如何调用这样的代码?我不是在这里问   关于SQLConnections,但MVVM最佳实践。 :)

为更复杂的模型操作/业务逻辑创建服务。将服务注入需要它们的视图模型中。 ICustomerService,IAccountService等

编辑:--------------------------------------------- ----------

你的第一个方法是正确的。关于共享模型是一个严重问题,因为保存方法绑定到视图模型类。视图模型将具有SaveCustomerCommand,在单击按钮时会触发该SaveCustomerCommand,因为它具有绑定。

CustomerModel将保留CustomerModel,无论_db.Save(CustomerModel)如何保留。因此,如果它是一个数据库,那么视图模型可能会引用一个上下文并发出CustomerModel。如果另一个视图模型需要操作CustomerService,它将通过使用上下文来实现。视图模型还可以引用CustomerModel来处理public class AddCustomerViewModel : Screen { private readonly ICustomerService _customerService; public AddCustomerViewModel(ICustomerService customerService) { _customerService = customerService; } //If button is named x:Name="SaveCustomer" CM will //bind it by convention to this method public void SaveCustomer(Customer customer) { _customerService.Save(customer); } } public class CustomerListViewModel : Screen { private readonly ICustomerService _customerService; private List<CustomerDisplayModel> _customers; public CustomerListViewModel(ICustomerService customerService) { _customerService = customerService; } public List<CustomerDisplayModel> Customers { get { return _customers; } set { _customers = value; NotifyOfPropertyChange(); } } //only fires once, unlike OnActivate() protected override void OnInitialize() { var customers = _customerService.LoadAllCustomers(); //could just use the model but this shows how one might map from //the domain model to a display model, AutoMapper could be used for this Customers = customers.Select(c => new CustomerDisplayModel(c)).ToList(); } } public interface ICustomerService { List<Customer> LoadAllCustomers(); void Save(Customer customer); } //same as button, Label named x:Name="CustomerName" will bind // to CustomerName public class CustomerDisplayModel { private readonly Customer _customer; public CustomerDisplayModel(Customer customer) { _customer = customer; } public string CustomerName { get { return _customer.Name; } set { _customer.Name = value; } } public string Surname { get { return _customer.Surname; } set { _customer.Surname = value; } } public string Address { get { return _customer.Address; } set { _customer.Address = value; } } } public class Customer { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public string Address { get; set; } } 的crud。

以下是这可能的样子:

SELECT