棱镜6使用Unity - 解决了看法视图模型没有命名规则 [英] Prism 6 with Unity - resolving view models for views without naming convention

查看:202
本文介绍了棱镜6使用Unity - 解决了看法视图模型没有命名规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有视图模型在我的WPF应用程序中使用DI与棱镜6和Unity解决,这工作。但是我不知道怎么告诉这些观点应该合并与查看模型的框架。



如果我用的惯例,即拥有的ViewModels和视图的命名空间,和类ViewA和ViewAViewModel一切正常,但是我想有更多的灵活性来命名,并组织我的课,这就是为什么我要以某种方式告诉框架明确其观点与视图模型去。我试过很多东西,但没有真正的作品。 。目前的解决方案,使应用程序运行,但视图模型不设置



下面是代码:



ViewA的.xaml

 <用户控件X:类=WPFDITest.Views.ViewA
的xmlns =HTTP:/ /schemas.microsoft.com/winfx/2006/xaml/presentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
的xmlns:MC =HTTP ://schemas.openxmlformats.org/markup-compatibility/2006
的xmlns:D =http://schemas.microsoft.com/expression/blend/2008
的xmlns:棱镜=HTTP ://prismlibrary.com/
棱镜:ViewModelLocator.AutoWireViewModel =真
MC:可忽略=D
D:DesignHeight =300D:DesignWidth =300> ;
<&StackPanel的GT;
< TextBlock的文本={结合ViewAMessage}/>
<文本框的文本={结合ViewAMessage,UpdateSourceTrigger =的PropertyChanged}/>
< / StackPanel的>
< /用户控件>



MainWindow.xaml

 <用户控件X:类=WPFDITest.Views.ViewA
的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/presentation
的xmlns :X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
的xmlns:MC =htt​​p://schemas.openxmlformats.org/markup-compatibility/2006
的xmlns :D =htt​​p://schemas.microsoft.com/expression/blend/2008
的xmlns:棱镜=htt​​p://prismlibrary.com/
棱镜:ViewModelLocator.AutoWireViewModel =真
MC:可忽略=D
D:DesignHeight =300D:DesignWidth =300>
<&StackPanel的GT;
< TextBlock的文本={结合ViewAMessage}/>
<文本框的文本={结合ViewAMessage,UpdateSourceTrigger =的PropertyChanged}/>
< / StackPanel的>
< /用户控件>



ViewAVM.cs

 公共类ViewAVM:BindableBase 
{
私人字符串viewAMessage;

公共ViewAVM(IModelA模型)
{
viewAMessage = model.HelloMsgA();
}

公共字符串ViewAMessage
{
{返回viewAMessage; }
集合{的SetProperty(REF viewAMessage,价值); }
}
}



Model.cs

 公共接口IModelA 
{
串HelloMsgA();
}

公共类MODELA:IModelA
{
公共字符串HelloMsgA()
{
返回你好从A!;
}
}



App.xaml.cs

 公共部分类应用
{
保护覆盖无效OnStartup(StartupEventArgs E)
{
群。 OnStartup(E);

变种bootstraper =新的引导程序();
bootstraper.Run();
}
}



Bootstrapper.cs

 公共类引导程序:UnityBootstrapper 
{
保护覆盖的DependencyObject CreateShell()
{
返回Container.Resolve<主窗口>();
}

保护覆盖无效InitializeShell()
{
Application.Current.MainWindow.Show();
}

保护覆盖无效ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType&下; IModelA,MODELA>(新ContainerControlledLifetimeManager());
Container.RegisterType<对象,ViewAVM>(ViewA);
}

保护覆盖无效ConfigureViewModelLocator()
{
ViewModelLocationProvider.SetDefaultViewModelFactory(类型=> Container.Resolve(类型));
}
}


解决方案

在有的通过棱镜源挖掘,我发现怎么做我想做的。我可以注册 ViewModelLocationProvider.Register 每个视图通过在视图模型的工厂方法。我创建的方法,不只是与方便的语法和使用的容器来解决视图模型给定类型:

 公共无效BindViewModelToView< TViewModel ,TView>()
{
ViewModelLocationProvider.Register(typeof运算(TView)的ToString(),()=> Container.Resolve< TViewModel>());
}

和有我如何使用它来绑定 ViewAVM ViewA ViewB 都使用相同的单一实例。

 公共类引导程序:UnityBootstrapper 
{
保护覆盖的DependencyObject CreateShell()
{
返回Container.Resolve< ;主窗口>();
}

保护覆盖无效InitializeShell()
{
Application.Current.MainWindow.Show();
}

保护覆盖无效ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType&下; IModelA,MODELA>(新ContainerControlledLifetimeManager());
Container.RegisterType&所述; ViewAVM>(新ContainerControlledLifetimeManager());
}

保护覆盖无效ConfigureViewModelLocator()
{
BindViewModelToView< ViewAVM,ViewA>();
BindViewModelToView< ViewAVM,ViewB>();
}
}



顺便说一句,据我可以告诉该人士透露,这是唯一可能的关联视图通过注册的工厂或使用他们的或定制的约定来查看模型ViewModelLocator,不要找一些DI魔法。


I am trying to have view models resolved using DI with Prism 6 and Unity in my WPF app and this works. However I don't know how to tell the framework which view should be merged with which view model.

If I use the convention, i.e. have ViewModels, and Views namespaces, and classes ViewA and ViewAViewModel everything works, however I would like to have more flexibility to name and organize my classes and this is why I want to somehow tell the framework explicitly which view goes with which view model. I tried many things, but nothing really works. Current "solution" makes app run but view model is not set.

Here is the code:

ViewA.xaml

<UserControl x:Class="WPFDITest.Views.ViewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <TextBlock Text="{Binding ViewAMessage}"/>
        <TextBox Text="{Binding ViewAMessage, UpdateSourceTrigger=PropertyChanged}"/>
    </StackPanel>
</UserControl>

MainWindow.xaml

<UserControl x:Class="WPFDITest.Views.ViewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <TextBlock Text="{Binding ViewAMessage}"/>
        <TextBox Text="{Binding ViewAMessage, UpdateSourceTrigger=PropertyChanged}"/>
    </StackPanel>
</UserControl>

ViewAVM.cs

public class ViewAVM : BindableBase
{
    private string viewAMessage;

    public ViewAVM(IModelA model)
    {
        viewAMessage = model.HelloMsgA();
    }

    public string ViewAMessage
    {
        get { return viewAMessage; }
        set { SetProperty(ref viewAMessage, value); }
    }
}

Model.cs

public interface IModelA
{
    string HelloMsgA();
}

public class ModelA : IModelA
{
    public string HelloMsgA()
    {
        return "Hello from A!";
    }
}

App.xaml.cs

public partial class App
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var bootstraper = new Bootstrapper();
        bootstraper.Run();
    }
}

Bootstrapper.cs

public class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void InitializeShell()
    {
        Application.Current.MainWindow.Show();
    }

    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        Container.RegisterType<IModelA, ModelA>(new ContainerControlledLifetimeManager());
        Container.RegisterType<object, ViewAVM>("ViewA");
    }

    protected override void ConfigureViewModelLocator()
    {
        ViewModelLocationProvider.SetDefaultViewModelFactory(type => Container.Resolve(type));
    }
}

解决方案

After some digging through Prism sources I found out how to do what I want. I can register each view with ViewModelLocationProvider.Register passing in a factory method for the view model. I created method that does just that with convenient syntax and uses container to resolve view model for given type:

public void BindViewModelToView<TViewModel, TView>()
{
    ViewModelLocationProvider.Register(typeof(TView).ToString(), () => Container.Resolve<TViewModel>());
}

And there is how I use it to bind ViewAVM to ViewA and ViewB both using same singleton instance.

public class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void InitializeShell()
    {
        Application.Current.MainWindow.Show();
    }

    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        Container.RegisterType<IModelA, ModelA>(new ContainerControlledLifetimeManager());
        Container.RegisterType<ViewAVM>(new ContainerControlledLifetimeManager());
    }

    protected override void ConfigureViewModelLocator()
    {
        BindViewModelToView<ViewAVM, ViewA>();
        BindViewModelToView<ViewAVM, ViewB>();
    }
}

By the way, as far as I can tell by the sources, it is only possible to associate view to view model through with ViewModelLocator by registering factories or by using their or custom convention, don't look for some DI magic.

这篇关于棱镜6使用Unity - 解决了看法视图模型没有命名规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆