WPF + MvvM + Prism

4

我是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);

我把构造函数改成了接收ViewModel,这样就可以将DataContext指向它:

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

我找到了其他的方法,例如:

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

获取/设置DataContext

干杯

2个回答

8

我喜欢Igor的建议,但是不希望viewmodel了解视图。我更喜欢依赖关系单向(视图 -> 视图模型 -> 模型)。

我的做法是ViewModel-First并仅将视图模板应用于视图模型。因此我会这样做:

MainViewModel mainViewModel = container.Resolve<MainViewModel>();

region.Add(mainViewModel, "MainView");
region.Activate(mainViewModel);

通过使用WPF datatemplate进行ViewModel -> View映射的添加(我认为这种方法在Silverlight中不可能)

App.xaml:

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

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

  • 不必修改构造函数以适应映射
  • 无需为容器中的IMyViewModel注册类型...您可以使用具体类型。我喜欢将我的注册保留在应用程序服务(如IViewRegistry或ILogger)中...那些类型的东西
  • 您可以使用特定视图范围的资源更改映射(如果您想要重用ViewModels但希望它们在应用程序的不同区域中看起来不同,这很好)

3
这是我们“传统”的MVVM开发者大多数人使用的方法...在引入PRISM时使用DataTemplate的问题很大程度上被忽略了,或者通过使用MVP示例而变得令人困惑。+1 - Tri Q Tran

0

你得到的东西是有意义的,在这两种情况下,都是一种以视图为先的方法来创建视图模型。也就是说,视图创建视图模型。在最初的例子中,视图模型是在视图之外创建的(有时被称为婚姻模式),但我认为这是相同的事情——视图的创建创建了视图模型。

如果这符合你的需求,请坚持使用它。另一种方法是ViewModel first,其中视图模型对视图具有依赖性,如下所示:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接