在DevExpress MVVM框架中,您可以定义两个标准ViewModel,继承自ViewModelBase。或者,您可以定义更好,更复杂的POCO ViewModels(see this link)。
要构建此类“POCO”视图模型,必须使用 ViewModelSource util。这将使标准虚拟类成为POCO ViewModel。
namespace DataAbstractWPF.ViewModels
{
[POCOViewModel]
public class EntityKindViewModel : Interfaces.ICreateEntityKindViewModel
{
}
}
然后,在XAML中,要实例化或定义这样的POCO视图模型,您必须:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModels="clr-namespace:DataAbstractWPF.ViewModels"
d:DataContext="{dxmvvm:ViewModelSource ViewModels:CreateEntityWizardViewModel}"
如果您将ViewModel动态或简单地传递给View
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModels="clr-namespace:DataAbstractWPF.ViewModels"
DataContext="{dxmvvm:ViewModelSource ViewModels:CreateEntityWizardViewModel}"
如果您希望ViewModel直接由XAML实例化。
您也可以通过代码
创建它ViewModelSource.Create<LoginViewModel>();
或者可以由框架创建的工厂。
var factory = ViewModelSource.Factory((string caption) => new LoginViewModel(caption));
factory("Login");
现在,使用Castle Windsor,我注册了这个:
container.Register(Component.For<Interfaces.ICreateEntityKindViewModel>().ImplementedBy<ViewModels.EntityKindViewModel>().LifestyleTransient());
container.Register(Component.For<Interfaces.ICreateEntityWizardViewModel>().ImplementedBy<ViewModels.CreateEntityWizardViewModel>().LifestyleTransient());
container.Register(Component.For<Interfaces.IMainWindowViewModel>().ImplementedBy<ViewModels.MainWindowViewModel>().LifestyleTransient());
container.Register(Component.For<Interfaces.ICreateEntityWizard>().ImplementedBy<Views.CreateEntityWizard>().LifestyleTransient());
container.Register(Component.For<Interfaces.IMainWindow>().ImplementedBy<Views.MainWindow>().LifestyleTransient());
container.Register(Component.For<Interfaces.ICreateEntityKind>().ImplementedBy<Views.EntityKind>().LifestyleTransient());
container.Register(Component.For<Interfaces.IShell>().ImplementedBy<Shell>().LifestyleTransient());
但是现在,当然, ViewModelSource 被完全绕过,曾经美丽的POCO视图模型现在只是一个无用的虚拟对象。
现在,我的问题是,如何使用ViewModelSource创建POCO viewModel,并允许它们由Castle Windsor注入?
非常感谢。
答案 0 :(得分:1)
我找到了解决方案:
创建此助手类
String variableNameId = rs1.getString("recording_id");
创建组件激活器
using System;
using System.Collections.Generic;
namespace DataAbstractWPF.Helpers
{
public class AttributeHelper
{
public static bool HasAttribute(Type implementation, Type attr)
{
object[] arr = implementation.GetCustomAttributes(true);
List<object> list = new List<object>(arr);
object attrib = list.Find(delegate (object o) { return ( attr.IsAssignableFrom(o.GetType()) ); });
return attrib != null;
}
}
}
像这样创建一个安装程序
using System;
using Castle.MicroKernel.ComponentActivator;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.Native;
using DataAbstractWPF.Helpers;
namespace DataAbstractWPF.Activators
{
class DXViewModelActivator : DefaultComponentActivator
{
public DXViewModelActivator(Castle.Core.ComponentModel model, Castle.MicroKernel.IKernelInternal kernel, Castle.MicroKernel.ComponentInstanceDelegate onCreation, Castle.MicroKernel.ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction)
{
Model.Implementation = TryGetPOCOType(Model.Implementation);
}
Type TryGetPOCOType(Type implementation)
{
if (AttributeHelper.HasAttribute(implementation, typeof(POCOViewModelAttribute)))
implementation = ViewModelSourceHelper.GetProxyType(implementation);
return implementation;
}
}
}
现在在你的构造函数中,依赖关系将被解析。
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using DataAbstractWPF.Helpers;
using DevExpress.Mvvm.DataAnnotations;
using DataAbstractWPF.Activators;
namespace DataAbstractWPF.Bootstrapping
{
public class Installers : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.Where(type => AttributeHelper.HasAttribute(type, typeof(POCOViewModelAttribute)))
.Configure(r => r.Activator<DXViewModelActivator>())
.LifestyleTransient()
.WithServiceDefaultInterfaces()
);
container.Register(Component.For<Interfaces.ICreateEntityWizard>().ImplementedBy<Views.CreateEntityWizard>().LifestyleTransient());
container.Register(Component.For<Interfaces.IMainWindow>().ImplementedBy<Views.MainWindow>().LifestyleTransient());
container.Register(Component.For<Interfaces.ICreateEntityKind>().ImplementedBy<Views.CreateEntityKind>().LifestyleTransient());
container.Register(Component.For<Interfaces.IShell>().ImplementedBy<Shell>().LifestyleTransient());
}
}
}