2015-12-17 5 views
0

В среде DevExpress MVVM вы можете определить как стандартные ViewModels, наследуемые от ViewModelBase. Или вы можете определить POCO ViewModels (see this link), которые лучше и сложнее.(WPF) DevExpress mvvm + замок Виндзор. Как создать модели просмотра POCO?

Чтобы построить такую ​​модель представления "POCO", вы должны использовать ViewModelSource Util. Это приведет к созданию стандартного фиктивного класса в POCO ViewModel.

namespace DataAbstractWPF.ViewModels 
{ 
    [POCOViewModel] 
    public class EntityKindViewModel : Interfaces.ICreateEntityKindViewModel 
    { 
    } 
} 

Затем в XAML, чтобы создать экземпляр или определить такую ​​ViewModel 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 к представлению динамически или просто

  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"); 

Теперь, используя замок Виндзор, зарегистрировать это:

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 полностью обойден, и некогда прекрасный ПОКО ViewModel теперь просто манекен бесполезно объект.

Теперь, мой вопрос заключается в том, как можно использовать и ViewModelSource для создания POCO viewModels, и позволить им быть введенным Castle Windsor?

спасибо.

ответ

1

Я нашел решение для этого:

Создать этот вспомогательный класс

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()); 
     } 

    } 
} 

И N в ваших конструкторах, зависимости будут разрешены.

public partial class MainWindow : Window, Interfaces.IMainWindow 
{ 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    public MainWindow(Interfaces.IMainWindowViewModel context) 
    { 
     InitializeComponent(); 
     this.DataContext = context; 
    } 
} 
Смежные вопросы