views:

424

answers:

1

I need all children of a view to know a piece of contextual information (the person they need to show). I also need the approach to be compatible with MVVM. I tried to do this with RegionContext in my Prism application. Here's my approach and problems:

I have a TabControl that I use View Injection to populate with views so that I can populate RegionContext:

From Shell.xaml:

<TabControl DockPanel.Dock="Right" cal:RegionManager.RegionName="TabRegion">

And here's my injection

//Create an instance of ContactView.xaml
contactView = CreateContactView(contact);
_regionManager.Regions["TabRegion"].Add(contactView, contactKey, true);

//"contact" being a simple entity of type Contact
RegionManager.SetRegionContext(contactViewb, contact);

What I expected was to be able to use an attached property to get the value of the RegionContext from any control that is a child of that DependencyObject (ContactView.xaml) via the RegionManager.RegionContext attached property:

From ContactView.xaml

<TextBlock Text="{Binding 
     RelativeSource={RelativeSource Self}, 
     Path=(cal:RegionManager.RegionContext)}"/>

But this doesn't work... I have to find ContactView.xaml to get it to work:

<TextBlock Text="{Binding 
     RelativeSource={RelativeSource 
          Mode=FindAncestor, 
          AncestorType={x:Type views:ContactView}}, 
     Path=(cal:RegionManager.RegionContext)}"/>

This is fine, however I'm going to allow modules to load views into ContactView and I would prefer they didn't have to know anything about ContactView.

I guess my question really is, how are you expected to load a complicated view with lots of controls and regions and have them all share one piece of context data?

What is the right way to do this? Scoped container? Write a new attached property that runs up the control hierarchy to find the RegionContext (ugh)? I'm not using RegionContext correctly? I'm open to anything. Suggest away.

+3  A: 

A better design avoids using RegionContext altogether. That is a sort of poor man's dependency injection in that it can host only one object. Using a scoped Unity container into which you inject the contact would lead to better testability of the ViewModel and will avoid the inevitable conflict when needing two items in RegionContext.

Jerry Bullard
Yeah... I see your point. I am concerned that the container will become a dumping ground for data, however it's likely the best place for "ambient" data to live.
Anderson Imes
Also... what the heck is RegionContext good for? The "Context" part of the name seems misleading.
Anderson Imes