Two views - one ViewModel

半世苍凉 提交于 2019-12-30 12:57:23

问题


I must have misunderstood the concept of ViewModels and Views. But at this moment I can't rebuild the application from ground and this time doing it better. My situation is that I have a view where the user can load files and read them, a plotter shows the graphs and some operations are implemented. I want to be able to generate reports (like summary) of the data but I want it in other view. I'm using ModernUI, this other view is in another tab.

What I want is have that two tabs synchronized, when I load a file in the "plotter tab", the file must be loaded in the other view too. For that I think what I need is to bind the view to the same ViewModel, where I have for example LoadedFiles = List<File>, so I will be able to achieve it. The problem is that if I bind it either

MainViewModel vm = new MainViewModel();
DataContext = vm;

or in XAML

<UserControl.Resources>
<UserControl.DataContext=local:MainViewModel/>
</UserControl.Resources>

I'm actually binding to different MainViewModels and the data is not shared anymore. Do I need some classes from MVVM libraries such Locator and so? How this could be done? What can I do in the future in order to have separate ViewModels for each View but the same (or different) data?


回答1:


You could create a new class that has your LoadedFiles property and then each unique view model can reference this class. You can share the one class with these shared properties between multiple view models. I am using MVVMLight's Locator with an Autofac container to inject this class into each of my view models (basically using Inversion of Control and Dependency Injection).

You can read up on Inversion of Control and Dependency Injection here.

Some sample code-

public MyClass
{
    public List<File> LoadedFiles{get; set;}
}

public ViewModelOne
{
    public MyClass MyClassInstance {get; set;}
    public ViewModelOne(MyClass myclass)
    {
        MyClassInstance = myclass
    }
}

public ViewModelTwo
{
    public MyClass MyClassInstance {get; set;}
    public ViewModelTwo(MyClass myclass)
    {
        MyClassInstance = myclass
    }
}

You could also use MVVMLight's Locator to set each View's DataContext to the appropriate View.

<UserControl x:Class="View1"             
             DataContext="{Binding ViewModel1, Source={StaticResource Locator}}"...>



回答2:


Store the VM in a parent VM's property, then bind the property to two ContentPresenters using different ContentTemplates (containing the respective views).




回答3:


You should ask yourself if both of your views should share the same viewmodel? Does they share the sameproperties in the view model or that they have different properties? If they should share the same viewmodel you should use locator create the viewmodel from the locator and pass the locator to the views. Otherwise, You should have two viewmodels. in order to keep minimal cuppling between the viewmodels you should use a service which known by both of the viewmodels (better via interfaces). One viewmodel notify the service about action that have been performed, and the second viewmodel has been handle that action (By register to event)

Good Luck,

M. Moshe



来源:https://stackoverflow.com/questions/17557811/two-views-one-viewmodel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!