Reputation: 1171
I use Prism's viewlocator to connect View and ViewModel, and I follow the convention by placing the View inside the view folder and ViewModel inside the viewmodel folder, and also adding suffix viewmodel to the name of the viewmodel class. It all works fine. I was just wondering how to connect multiple viewmodels to a single view?
For example, I have:
View: CustomerView
and in XAML I simply use: prism:ViewModelLocator.AutoWireViewModel="True"
ViewVodel: CustomerViewModel
now I want to add CustomerViewModel2
, but it is not going to work, because it doesn't match the view's name
Upvotes: 0
Views: 2393
Reputation: 15197
As I mentioned in my comment, there's no such possibility to directly connect a single view with multiple (same-level) view models.
You have to split up your view into a master and (several) child views (either logically in XAML or physically by moving child views into separate UserControl
s).
Here are my suggestions.
Define a master view that will contain the regions:
<Window>
<StackPanel Orientation="Vertical">
<ContentControl prism:RegionManager.RegionName="Region1"/>
<ContentControl prism:RegionManager.RegionName="Region2"/>
</StackPanel>
</Window>
Create child views that will be "inserted" (in PRISM's terminology - injected) into your main view:
<UserControl x:Class="UserControl1">
<Grid/>
</UserControl>
<UserControl x:Class="UserControl2">
<Grid/>
</UserControl>
And finally you have to register in PRISM your views so they can be instantiated:
// Obtain the region manager over DI
IRegionManager regionManager;
regionManager.RegisterViewWithRegion("Region1", typeof(UserControl1));
regionManager.RegisterViewWithRegion("Region2", typeof(UserControl2));
Each of these child views will have its own view model. You can use the PRISM's view model locator to auto-wire them.
Your master view:
<Window>
<Window.Resources>
<DataTemplate DataType="vm:ViewModel1">
<v:UserControl1/>
</DataTemplate>
<DataTemplate DataType="vm:ViewModel2">
<v:UserControl2/>
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Items}"/>
</Window>
Add the child view models into the Items
collection of your master view model, and WPF will create the views and auto-wire the view models with them for you.
class MasterViewModel : BindableBase
{
public IEnumerable<BindableBase> Items
{
get { return new[] { new ViewModel1(), new ViewModel2() }
}
}
Of course, you can use DI for instantiating your view models.
Something like this:
class MainViewModel : BindableBase
{
public ViewModel1 ViewModel1 { get; private set; }
public ViewModel2 ViewModel2 { get; private set; }
}
In your main view, you will have to set up your bindings accordingly.
<Window>
<StackPanel>
<TextBlock Text="{Binding ViewModel1.SomeValue}"/>
<TextBox Text="{Binding ViewModel2.SomeValue}"/>
</StackPanel>
</Window>
Upvotes: 2
Reputation: 31724
You could expose child view models as properties of the main view model for the page, then prefix the paths to the child view model in your bindings with the property name.
Upvotes: 1