WPF + MvvM +棱镜

发布于 2024-08-31 02:23:15 字数 785 浏览 4 评论 0原文

我是 Wpf & 的新手。 Mvvm world ,但我找到了几个例子,只是发现有一些不同的方法来实例化模型。我想知道最好/正确的方法。两种方法都使用 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;

get/set DataContext

欢呼

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 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月棠 2024-09-07 02:23:16

我喜欢伊戈尔的建议,但视图模型不了解视图。我更喜欢我的依赖项朝一个方向发展(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 但又想要它们在应用程序的不同区域看起来不同

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
〆一缕阳光ご 2024-09-07 02:23:16

您得到的结果是有意义的,在这两种情况下都是视图优先的方法来创建视图模型。即视图创建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);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文