Referencing ViewModel DataContext in PRISM

We all know that in PRISM views sitting inside Regions. And these Regions are logical containers flagged to Container controls in Shell UI. So what if you have a Binding setup on Shell which actually needs to hook into the ViewModel of the current view loaded in the Region. In other words, say if you are using a tab control as your main details(or workspace) region, and you want that the header content of each tabitem that opens, should have a lable which will be pulled from database and it will be exposed as a public property of ViewModel of that View.

In such cases, Binding gets a bit trickly and if you are not careful with the syntax, it might not get your the correct value or event showup as BindingError in the output window. You may even get very unhelpful message in output window like: “Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is ‘VisualBrush’ (HashCode=20308853); target property is ‘Visual’ (type ‘Visual’)”

So how you solve it. Here is the syntax:

<Button Command=”{Binding Path=DataContext.DataContext.CloseCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}”/>

This is actually doing deep level referencing. It is first referencing the current container i.e. tabitem and then using its datacontext which will be the current view loaded in the tabitem. This is the default mechanism of wpf  that the view will become the datacontext of the current container and then a second .DataContext will reference the ViewModel of the View which is want we want. In the above example, I am binding the command type exposed by my ViewModel to the button on the view which is loaded in the shell region however, the template for this tabitem is actually defined inside the Shell.xaml file!

Please note: This xaml binding syntax is only needed if you are trying to reference the viewmodel from within a datatemplate. If you are not in a DataTemplate, then in place like Style setter, you can just use the standard DataContext.[PropertyName] and WPF will make sure that it maps it correctly at runtime.

Have a good day!

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s