0

我试图找到创建视图模型和服务的最佳实践(服务只是与服务器对话并将数据返回给视图模型)。我见过两种不同的方法。

  1. 使用视图模型定位器
  2. 使用行为(我不确定这是否是好方法)

对于第二种方法,您在 UserControl 上定义一个行为,并在附加事件上创建一个视图模型实例和一个服务实例并将它们放在一起。

protected override void OnAttached()
    {
        var service = Activator.CreateInstance(ServiceType)
        var viewModel = Activator.CreateInstance(ModelType);
        base.AssociatedObject.DataContext = viewModel;
        base.OnAttached();
    }

并在您的用户控件 xaml

<i:Interaction.Behaviors>
    <be:ViewModelBehavior ViewModelType="{x:Type vm:ViewModel1}"  ServiceType="{x:Type serv:Service1}"/>
</i:Interaction.Behaviors>

这是对行为的一种很好的利用,还是我应该只使用视图模型定位器模式。

4

1 回答 1

1

您的行为有一个明显的缺点 - 在每个用户控件中,您必须指定行为、ViewModelType(以及 ServiceType)。

您可以执行以下操作:

<UserControl x:Class="MyApp.HomePage" ....
             local:ViewModelLocator.AutoWireViewModel="True">
   ...
</UserControl>

当您将附加属性设置为 true 时,ViewModelLocator将创建视图模型实例并将其分配给用户控件的数据上下文。使用ViewModelLocatator命名约定来确定视图模型的类型。在这种情况下它可能是HomePageViewModel,因为视图类型是HomePage.

这种方法由 Prism.Mvvm 库中的 PRISM ViewModelLocator 使用,但我建议您编写自己的方法,因为它非常简单。

它与您的基本相似ViewModelBehavior,但有两个不同之处:

  1. 该行为作为附加属性实现。它允许您在 Style 中指定行为,因此它将应用于使用此样式的任何用户控件。您不能在样式中指定 Interaction.Behaviors。

  2. 它使用命名约定而不是显式设置 ViewModelType


关于服务,应该作为参数传递给 viewmodel:您可以使用 IoC 模式。这是描述模式的伪代码:

public class MyViewModel(IMyService service) {...}

//at application startup you setup the IoC container:
IoC.Setup<IMyService>(new MyService());

//later
var viewModel = IoC.GetInstance<MyViewModel>(); //MyService will be passed as to ctor
于 2015-11-06T15:11:50.480 回答