1

我一直在使用在线提供的 MVVM 示例中通常提到的基本设计模式编写我所有的 MVVM 应用程序。我遵循的模式如下所述:

模型

本节包括 DTO 类及其属性和接口 IDataService 等:

 public class Employee
 {
   public string EmployeeName { get; set; }
   public string EmployeeDesignation { get; set; }
   public string EmployeeID { get; set; }
 }

public interface IDataService
{
  public Task<Employee> GetEmployeeLst();
}

代理人

该层包含实现 IDataservice 的 Dataservice 调用,例如:

public class DataService : IDataService
{
   public async Task<Employee> GetEmployeeLst()
   {
     // Logic to get employee data from HTTPClient call
   }
}

视图模型

该层包含 ViewModel 以及对从中接收所有数据的模型和代理层的引用:

public class BaseViewModel
{
    public BaseViewModel(INavigationService nav, IDataService data, IAESEnDecrypt encrypt, IGeoLocationService geoLocation, IMessageBus msgBus, ISmartDispatcher smtDispatcher)
    {
    }

    // This also include common methods and static properties that are shared among most of the ViewModels
}

所有的 ViewModel 都继承 BaseViewModel。每个 viewModel 还包含在 UI 触发事件时执行的 Delegatecommand。然后,它通过在代理层调用 DataService 从服务器获取数据并执行业务逻辑并填充绑定到视图的 ViewModel 中的属性。对于每个 View,都有一个绑定到 View 的 Datacontext 的 VM。ViewModel 还负责启动我使用触发器启动故事板的动画,该故事板绑定到我在 VM 中的枚举以更改这些触发器的状态,例如: http: //www.markermetro.com/2011/05/technical/ mvvm-friendly-visual-state-management-with-windows-phone-7/

看法

在这一层中,我拥有所有视图、用户控件和业务逻辑,并实现了某些依赖项,例如 GeoLocation 服务、AES 加密、视图之间的 NavigationService 等。

每个视图都有 .xaml 和 .xaml.cs 文件。在 .xaml.cs 文件中,我将视图的数据上下文与 VM 绑定,如下所示:

this.DataContext = App.IOConatiner.GetInstance<DashboardViewModel>();

从这里开始,所有的绑定都会发生。

我的问题是,最近我知道这种模式没有遵循我在回答我的问题时了解到的 SOLID 设计模式: Simple Injector injection multiple dependency in BaseClass

我正在努力按照我之前的问题答案中给出的建议来改变我的设计。但我无法得到一些东西,比如:

  1. 当前 View Datacontext 绑定到 ViewModel,因此所有控件都由 VM 中的属性控制。我将如何使用处理器/服务或 DialogHandler 将其更改为上述模式?

  2. 我正在使用绑定到 UI 元素的命令属性的委托命令。执行这些命令会发生某些动作,例如动画,显示用户控件。如何在命令模式中做到这一点?

  3. 我怎样才能开始改变我当前的实现,以用最好的方法来适应所有这些变化?

4

2 回答 2

2

首先回答你的问题3

我怎样才能开始改变我当前的实现,以用最好的方法来适应所有这些变化?

这是您需要采取的第一步。这不是对当前代码进行一些智能重构的情况。您将需要退后一步并设计应用程序。我曾经读过一些关于(重新)设计的好博客。

在开始编写任何代码之前,定义您希望向用户显示多少种不同的基本类型的视图?例如:

  1. 只显示(任何类型的)数据
  2. 编辑数据
  3. 提醒用户
  4. 询问用户输入
  5. ...

当您定义了不同的需求时,您可以将其转换为针对它们所服务的工作量身定制的特定界面。例如,允许用户编辑数据的视图通常具有如下界面:

public interface IEditViewModel<TEntity>
{
    public EditResult<TEntity> EditEntity(TEntity entityToEdit)();
}

一旦你把这个设计的每一个细节都做好了,你必须决定如何向用户展示你的观点。我为此使用了另一个接口来为我处理此任务。但您也可以决定让导航服务处理此类任务。

有了这个框架,您就可以开始编写您的实现了。

当前 View Datacontext 绑定到 ViewModel,因此所有控件都由 VM 中的属性控制。我将如何使用处理器/服务或 DialogHandler 将其更改为上述模式?

这在本设计中不会改变。您仍然会将您的视图绑定到您的视图模型并将数据上下文设置为视图模型。对于很多视图,使用像 Caliburn Micro 这样的 MVVM 框架会派上用场。基于Convention over Configuration,这将为您完成很多 MVVM 工作。从这个模型开始,会使学习曲线更高,所以我的建议是从手工开始。您将通过这种方式了解在此类 MVVM 工具的保护下会发生什么。

我正在使用绑定到 UI 元素的命令属性的委托命令。执行这些命令会发生某些动作,例如动画,显示用户控件。如何在命令模式中做到这一点?

我不确定您在此处提到的命令模式是否是我在上一个答案中建议您的命令模式。如果是这样,我认为您需要重新阅读此博客,因为这与我认为您在此问题中所指的命令完全无关。

动画之类的东西是视图的责任,而不是视图模型。所以视图应该处理所有这些东西。XAML 有很多方法可以处理这个问题。在这里我无法解释。一些想法:触发器依赖属性

另一种选择:代码后面!如果逻辑纯粹是与视图相关的 IMO,则将此代码放在视图后面的代码中并不是致命的罪过。只是不要急于做一些灰色地带的事情!

对于仅在视图模型中执行方法调用的命令,仍然可以使用 ICommand,并且像 Caliburn 这样的 MVVM 工具会自动执行此操作...

仍然:松开基类....

于 2015-02-11T22:32:54.543 回答
0

如果 viewmodel 基类自己不使用这些服务,为什么要在 viewmodel 基类中注入所有这些服务?

只需在需要这些服务的派生视图模型中注入您需要的服务。

于 2015-02-08T19:51:26.387 回答