WPF + MvvM + Prism

后端 未结 2 2005
故里飘歌
故里飘歌 2021-02-06 16:31

I am new in the Wpf & Mvvm world , but I have found a couple of examples and just found that there is some different way to instantiate the model. I would like to know the b

相关标签:
2条回答
  • 2021-02-06 17:10

    What you got there makes sense and in both cases is a View-first approach to creating a viewmodel. I.e. the view creates the ViewModel. In the original example the viewmodel is created outside of the view (and is sometimes referred to as marriage pattern), but as far as I am concerned that's the same thing - creation of the view creates the ViewModel.

    If this suits your needs stick with it. Another approach you might look into is ViewModel first where the viewmodel takes a dependency on the view like so:

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

    Then you can inject this view like so:

    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);
    
    0 讨论(0)
  • I like Igor's suggestion, but without the viewmodel having knowledge of the view. I prefer my dependencies to go one direction (View -> ViewModel -> Model).

    What I do is ViewModel-First and just DataTemplate the viewmodel. So I do this:

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

    With the addition of the ViewModel -> View mapping done with a WPF datatemplate (I don't think this approach is possible with Silverlight, though)

    App.xaml:

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

    That's it! I love this approach. I like the way it feels like magic. It also has the following advantages:

    • Don't have to modify constructors to suit the mapping
    • Don't have to register type for IMyViewModel in the container... you can work with concrete types. I like to keep my registrations to application services like IViewRegistry or ILogger... those kinds of things
    • You can change the mapping using resources scoped to a particular view that a region is in (this is nice if you want to reuse your ViewModels but want them to look different in different areas of the application
    0 讨论(0)
提交回复
热议问题