【问题标题】:WPF + MvvM + PrismWPF + MvvM + 棱镜
【发布时间】:2011-02-15 23:34:03
【问题描述】:

我是 Wpf 和 Mvvm 世界的新手,但我找到了几个示例,发现有一些不同的方法可以实例化模型。我想知道最好/正确的方法。两种方式都使用 Unity

我发现了什么:

var navigatorView = new MainView();
navigatorView.DataContext = m_Container.Resolve<INavigatorViewModel>();
m_RegionManager.Regions["NavigatorRegion"].Add(navigatorView);

我做了什么:

var navigatorView = m_Container.Resolve<MainView>;
m_RegionManager.Regions["NavigatorRegion"].Add(navigatorView);

我更改了构造函数以接收视图模型,因此我可以将数据上下文指向它:

public MainView(NavigatorViewModel navigatorViewModel)
{
 this.DataContext = navigatorViewModel;
}  

我发现了另一种方式的其他示例,例如:

...vm = new viewmodel 
...m = new model
v.model = vm;

获取/设置数据上下文

干杯

【问题讨论】:

    标签: wpf mvvm unity-container prism


    【解决方案1】:

    我喜欢 Igor 的建议,但没有视图模型了解视图。我更喜欢我的依赖项朝一个方向发展(View -> ViewModel -> Model)。

    我所做的是 ViewModel-First 和 DataTemplate 视图模型。所以我这样做:

    MainViewModel mainViewModel = container.Resolve<MainViewModel>();
    
    region.Add(mainViewModel, "MainView");
    region.Activate(mainViewModel);
    

    添加 ViewModel -> 使用 WPF 数据模板完成视图映射(不过,我认为 Silverlight 无法使用这种方法)

    App.xaml:

    <Application.Resources>
         <DataTemplate DataType="{x:Type viewModels:MainViewModel}">
              <views:MainView />
         </DataTemplate>
    </Application.Resources>
    

    就是这样!我喜欢这种方法。我喜欢它感觉像魔术的方式。它还具有以下优点:

    • 不必修改构造函数以适应映射
    • 不必在容器中为 IMyViewModel 注册类型...您可以使用具体类型。我喜欢将我的注册信息保留在 IViewRegistry 或 ILogger 等应用程序服务中……诸如此类的事情
    • 您可以使用范围为某个区域所在的特定视图的资源更改映射(如果您想重用 ViewModel 但希望它们在应用程序的不同区域中看起来不同,这很好

    【讨论】:

    • 这是我们大多数“传统” MVVM 开发人员使用的方法......在介绍 PRISM 时使用 DataTemplate 的问题被忽略了,或者与 MVP 示例的使用混淆了。 +1
    【解决方案2】:

    你得到的东西是有道理的,在这两种情况下都是一种视图优先的方法来创建一个视图模型。 IE。视图创建 ViewModel。在原始示例中,视图模型是在视图之外创建的(有时称为 marriage pattern),但就我而言,这是同一件事 - 视图的创建会创建 ViewModel。

    如果这符合您的需求,请坚持下去。您可能会研究的另一种方法是 ViewModel 首先,其中 viewmodel 依赖于视图,如下所示:

    //In the bare-bones(i.e. no WPF dependencies) common interface assembly
    
    interfac IView {
      void ApplyViewModel(object viewmodel);
    }    
    
    interface IMainView : IView {
      //this interface can actually be empty.
      //It's only used to map to implementation.
    }
    
    //In the ViewModel assembly
    
    class MainViewModel {
      public MainViewModel(IMainView view) {
        view.ApplyViewModel(this);
      }
    }
    
    public partial class MainView : UserControl, IMainView {
      void ApplyViewModel(object viewmodel){
        DataContext = viewmodel;
      }
    }
    

    然后你可以像这样注入这个视图:

    IRegion region = regionManager.Regions["MainRegion"];
    
    //This might look strange as we are resolving the class to itself, not an interface to the class
    //This is OK, we want to take advantage of the DI container 
    //to resolve the viewmodel's dependencies for us,
    //not just to resolve an interface to the class.
    MainViewModel mainViewModel = container.Resolve<MainViewModel>();
    
    region.Add(mainViewModel.View, "MainView");
    region.Activate(ordersView.View);
    

    【讨论】:

      猜你喜欢
      • 2013-12-27
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 2018-11-10
      • 2011-04-02
      • 1970-01-01
      相关资源
      最近更新 更多