Multiple Views Construction

Topics: Prism v4 - WPF 4
Oct 3, 2012 at 3:00 PM


I was hoping someone can guide me in the right direction.

Here is the issue I am running into.  We have a shell with a single MainRegion, which is a content control, in another view in one of the modules, I have a tab control that is made up of multiple Views & View Models, for example on Tab #1 I have First and Second views andtheir view models, and on the second tab I have a third and fourth view and view model.   When I run the application it builds and runs, but only the first view constructor is called.  

I can not change the main region to be a tab control, since it will break other functionality. 

How can I write code to create the tab control and have all 4 views & view models constructors called everytime the view is constructed.

Thanks in advance.

Oct 3, 2012 at 9:48 PM


I believe I am not completely understanding your scenario.

When a view is constructed, one of its constructor will be always invoked. As far as I know it's not possible to create an instance of any class without invoking a constructor. Also, after an object (or in this case, view) is created, the constructor of that instance should never be executed again as the object is already constructed.

If your views are being shown, it means that they were constructed, initialized an loaded.

On the other hand, if in your scenario you are obtaining the views through the container and the constructor of these views is only called the first time each view is requested, this could be related to how the views' types are registered in the container. If the views' types are registered as singletons in the container, the container will only create one instance of each view and will return always the same instance. Therefore, the views are only constructed once.

It would be helpful if you could provide more information about your scenario and about what you are trying to achieve so that we can help you further with this.


Damian Cherubini

Oct 3, 2012 at 10:09 PM


Thank you so much for your reply, Let me try to claraify. 

The views gets created, but the view models for each one of those views does not get instanitated. 

 //_regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(DetailsView));
            //_regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof (OrderLinesView));
            //_regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(StatusView));

I try to do that for each view I need, but the datacontext for all of the views is the first view model
which view contains the views.   

I guess the best question how do I instantiate all the views & view models for that perticular case.

I hope i made more sense, if not let me know and I can see if I can elaborate further.
Oct 3, 2012 at 10:19 PM
Edited Oct 3, 2012 at 10:28 PM

I guess another way to say it is, I have a composite view which consists of 4 views & view models.

The views get created fine when I have them in different tabs.  The problem I am having is that the viewmodel for each view I want to use does not get called although I have it set as UNITY DEPENDENCY PROPERTY in each view.  And the DataContext for all views gets set to be the first view model I created. 

Or you can say, how I can create a composite view (one consisting of multiple views) with each view having it's own view model.  Currently the views get created but the data context is always set to the first view model.

I want each view to have it's own view model.

Can you help.

Oct 4, 2012 at 5:54 AM
Edited Oct 4, 2012 at 3:03 PM

The location above you would find a project that demonstrate the issues I am running into.   In the project, I have an order module.  In that module I have a view called "Composite View", that view consists of 3 additional views (OrderView, LinesView, NotesView).  As you can tell each one of these views have their own view model.   If you run the application you would see that all 3 views are rendered, which is correct.  

What I am struggling with is how to get the views to construct their viewmodels.  Meaning if you look at the code behind of any of the other 3 views (OrderView, LinesView, NotesView) you will find a [Dependency] for their viewmodels.   but if you look at the data context for each view you would notice that it is not the views prespective viewmodel instead they are all CompositeViewModel instead.  I want to be able to have the corosponding viewmodel be the datacontext for each view.

In the constructor of each view model there is a debug statement that does not fire. 

Can you help? 

Can you please reply and let me know as soon as possible if you understand my issue, if not I can try to elaborate further.

Oct 4, 2012 at 6:44 PM


Thanks for providing us with a repro-sample application. It was very useful to troubleshot this issue.

The problem you are experiencing is caused by the fact that you are creating the aforementioned views directly in XAML, instead of creating the views through the container.

Based on my understanding, when the container creates a view it will inject the corresponding types in all the properties marked with a Dependency attribute. However, the view needs to be created through the container in order for it to inject the corresponding dependencies. If instead the view is constructed manually, the attribute becomes meaningless, as the container doesn't have any participation in the construction of the view. This is also true when using construction injection. Finally, as due to this no DataContext is set for those views, the views inherit the DataContext for their parent view, that is the CompositeViewModel of the CompositeView.

As far as I know, when creating an instance of a control (or view) in XAML, the container is not involved.

// As a simplification, you can think of this sentence:
<views:OrderView />

// As being equal to this one:
var orderView = new OrderView();

In my opinion, an easy approach to change this and delegate the construction of the views to the container would be to make the TabControl of the CompositeView a region and insert the corresponding views in it, for example, using the view discovery method:

<!-- CompositeView -->
<TabControl prism:RegionManager.RegionName="{x:Static common:RegionNames.TabRegion}">
    <!-- The views that were declared in XAML are removed -->        
// ModuleInitilizer
public void Initialize()
    _regionManager.RegisterViewWithRegion( RegionNames.MainRegion, typeof (CompositeView));
    _regionManager.RegisterViewWithRegion( RegionNames.TabRegion, typeof(OrderView));
    _regionManager.RegisterViewWithRegion( RegionNames.TabRegion, typeof(LinesView));
    _regionManager.RegisterViewWithRegion( RegionNames.TabRegion, typeof(NotesView));
When using the view discovery approach, Prism will try to create the specified views' types using the container; therefore, the dependencies of those views should be resolved correctly.

On the other hand, if for some reason you are unable to apply the aforementioned changes and you need to create the views directly in XAML, another possible approach could be to manually obtain the corresponding view models in the views' constructors using the ServiceLocator:

// OrderView's constructor
public OrderView()
    this.DataContext = ServiceLocator.Current.GetInstance<OrderViewModel>();

I hope you find this useful to solve this problem,

Damian Cherubini

Oct 9, 2012 at 11:02 PM

Thank you for your response, I am able to use the service locator with success. 

I am running into this following problem.   I am using non-linear navigation similar to the concept used here :

I am using the eventaggregator to pass data from the (composite view model) to the other view models I have.

The issue is that the first order I opened gets the values from the second order I opened, meaning the event aggregator data gets assigned to all the view models that are open, I know I can filter the event aggregator, but how I pass the order Id to all the view models the first time?  or how can I solve this. 

I hope you can help.



Oct 10, 2012 at 2:45 PM


I believe you could try passing the corresponding order Id as a parameter the first time you navigate to each view, an example of this can be seen in the Region Navigation Pipeline sample when navigating to the different ItemViews, and where the navigation parameters are retrieved and set on the initial navigation to each of this views in the OnNavigatedTo method of the ItemViewModel class:

//only set the current item on the initial navigation
if(navigationContext.Parameters != null && this.CurrentItem == null) {
                this.CurrentItem = navigationContext.Parameters[Constants.Global.Item];

This way once you set the corresponding Id to each view model, you could filter the published events based on this information.

For additional information on how to pass parameters during navigation, you could check the following section of the documentation:

I hope you find this handy,

Agustin Adami

Oct 10, 2012 at 3:37 PM

I understand what you are saying and I understand about passing the ID during the navigation.  Unfortunatly, that is not what is going on.

I am only navigating to the composite view, but that composite view can be created N-number of times.   The composite view publish events via eventaggregator to the other view models to pass data for the views to display.  But everytime the event aggregator fires, all the view models gets updaed with the latest value, the navigation interface IConfirmNavigationRequest does not get executed at all on the child views. 

Any suggestions?

Oct 11, 2012 at 2:18 PM


Based on my understanding if the view models of your inner views are subscribing to this event, you will have to implement the necessary logic to pass the Id information during the construction of the inner view models to filter the published event. Based on my understanding how to achieve this will depend on which approach your are using to compose your composite views.

In my opinion, if you are you are creating the inner views directly in XAML like mentioned above in this thread, this will increase the complexity to pass the required information without coupling the view models to the parent view. If following this approach the only clean approach I could think of, could be by sharing the DataContext of the parent view, as the child elements could inherit the DataContext of their parent element, although making this decision would depend on your personal preferences and design choices.

On the other hand, if you decide to compose your composite views by benefiting of Prism regions, then I believe you could have other options like passing the Id information using a Region Context, which will allow you to share contextual information between the view that is hosting a region and a view that is inside a region letting you to communicate with the inner views in a loosely couple way, an example of this can be seen in the TabRegion defined in the UI Composition QuickStart, additionally for more information about this approach you could check the Communicating Between Loosely Coupled Components chapter of the documentation.

Also, I believe another possibility when using Prism regions, could be to define this required initialization logic of your composite views in a controller class that will be en charge of injecting the corresponding views with their corresponding view model values set when initialized, this will allow you to react to the events as expected. Examples using this kind of structure to compose your UI can be seen in the UIComposition Lab and Communication Lab of the Prism Training Kit.

I hope this help you to analyze which approach will suit best your needs,


Agustin Adami