WPF - 使用行为来实例化视图模型和服务
WPF - Using behaviors for instantiating view model and services
我正在尝试寻找创建视图模型和服务的最佳实践(服务只是与服务器对话,return 数据返回视图模型)。我见过两种不同的方法。
- 使用视图模型定位器
- 使用行为(我不确定这是否是好方法)
对于第二种方法,您在 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>
这是对行为的良好使用,还是我应该只使用视图模型定位器模式。
您的行为有一个明显的缺点 - 在每个用户控件中,您必须指定行为、ViewModelType(以及 ServiceType)。
您可以执行以下操作:
<UserControl x:Class="MyApp.HomePage" ....
local:ViewModelLocator.AutoWireViewModel="True">
...
</UserControl>
当您将附加的 属性 设置为 true 时,ViewModelLocator
将创建视图模型实例并将其分配给用户控件的数据上下文。 ViewModelLocatator
使用命名约定来确定视图模型的类型。在这种情况下,它可能是 HomePageViewModel
,因为视图类型是 HomePage
.
Prism.Mvvm 库中的 PRISM ViewModelLocator 使用了这种方法,但我建议您自己编写,因为它非常简单。
基本与你的ViewModelBehavior
相似,但有两点不同:
该行为已按附件 属性 实现。它允许您在 Style 中指定行为,因此它将应用于任何使用此样式的用户控件。您不能在样式中指定 Interaction.Behaviors。
它使用命名约定而不是显式设置 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
我正在尝试寻找创建视图模型和服务的最佳实践(服务只是与服务器对话,return 数据返回视图模型)。我见过两种不同的方法。
- 使用视图模型定位器
- 使用行为(我不确定这是否是好方法)
对于第二种方法,您在 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>
这是对行为的良好使用,还是我应该只使用视图模型定位器模式。
您的行为有一个明显的缺点 - 在每个用户控件中,您必须指定行为、ViewModelType(以及 ServiceType)。
您可以执行以下操作:
<UserControl x:Class="MyApp.HomePage" ....
local:ViewModelLocator.AutoWireViewModel="True">
...
</UserControl>
当您将附加的 属性 设置为 true 时,ViewModelLocator
将创建视图模型实例并将其分配给用户控件的数据上下文。 ViewModelLocatator
使用命名约定来确定视图模型的类型。在这种情况下,它可能是 HomePageViewModel
,因为视图类型是 HomePage
.
Prism.Mvvm 库中的 PRISM ViewModelLocator 使用了这种方法,但我建议您自己编写,因为它非常简单。
基本与你的ViewModelBehavior
相似,但有两点不同:
该行为已按附件 属性 实现。它允许您在 Style 中指定行为,因此它将应用于任何使用此样式的用户控件。您不能在样式中指定 Interaction.Behaviors。
它使用命名约定而不是显式设置 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