开发者

WPF + MvvM + Prism

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 instant开发者_运维问答iate the model. I would like to know the best/correct way to do it. both ways are using Unity

What I've foud:

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

What I did:

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

and I changed the constructor to receive viewmodel so I can point the datacontext to it:

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

Other examples I've found another way like:

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

get/set DataContext

cheers


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜