5
Vote

Sync ActiveAware state of views throughout scoped regions

description

"I have a view that was added to a scoped region. This view references a composite command that is defined globally (static) to the application. I toggle the active state of all commands registered with the composite command when the active state of the view changes, i.e., IActiveAware. My issue is that the scoped view is always active because scoped views are never made aware of when a parent view is activated or deactivated. I have written a region behavior called SyncIsActiveAwareBehavior which syncs the active state of scoped views based upon the active state of a parent view (owner of the scoped region,) but I'm not sure if this is the best way to handle this type of scenario. Is there any guidance on how best to work with scoped regions? It seems like Prism really breaks down once you have to manage a lot of scoped regions, say in a MDI interface. I'm hoping that there is some guidance in this area currently and that future versions of Prism will provide a better programming model for dealing with scoped regions."
 
More information here:
http://compositewpf.codeplex.com/discussions/100423

file attachments

comments

GuYsH wrote Apr 6, 2011 at 6:35 AM

This fix would be greatly appreciated.
It's the intuitive and expected functionality and a lot of "ugly" code has to be written to get around it.

tearaway_Tea wrote May 20, 2011 at 7:19 PM

Hey, is it possible to get the implementation of yours SyncIsActiveAwareBehavior? Could you attach a file or something. Thanks!

GuidoMaliandi wrote May 23, 2011 at 5:26 PM

Hi,

I'm posting your comment in the original thread (http://compositewpf.codeplex.com/discussions/100423), so that the user jcain00, who has developed the implementation of the SyncIsActiveBehavior is notified of your request.

Thanks,

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

KeithW wrote Jun 17, 2011 at 11:03 AM

This would be really nice, perhaps somethning called NestedRegionActiveAwareBehavior. However using the VisualTreeHelper may be expensive, however I don't know how else you'd do it.

Also if you add an object to the view, and are expecting the xaml engine to bind it to a datatemplate, within that datatemplate you had regions. How do you know in your behavior that then need to be set active.

tearaway_Tea wrote Jun 17, 2011 at 4:52 PM

Guys,

I made the recursive active aware behavior. It works pretty good for me. It does go through the all scoped regions and looking for IActiveAware implementors the same way as original RegionActiveAwareBehavior does.

I'm attaching the class. Have fun.

rumzeus wrote Jul 22, 2011 at 12:23 PM

RecursiveRegionActiveAwareBehavior.cs does not work for us when calling IRegion.Activate(view) for nested views where IActiveAware.IsActive should remain false. (e.g. during startup when adding views and activating them to avoid TabControls without an active tab.)

The attached NestedRegionActiveAwareBehavior replaces it and the normal RegionActiveAwareBehavior, and is deactivated by default to avoid the above problem. Small quirk: The bootstrapper should call NestedRegionActiveAwareBehavior.SetIsActive(regionManager, true); after setting the region manager to activate the behavior in all top level regions.

aadami wrote Mar 8, 2012 at 6:22 PM

Hi,

For those interested in this subject, you might find it useful to know that scenarios where it’s desired to keep the active state of views inside a scoped region in sync with the parent view are now supported since Prism 4.1 release (http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=28950).

To make this possible the RegionActiveAwareBehavior behavior was modified, which now updates child views Active state only if they are decorated with an attribute defined as SyncActiveState. Therefore, by adding this attribute to the child view or view model implementing IActiveAware, it’s possible to keep them in sync, unless the child view is not in the Region’s ActiveViews collection (in that case its IsActive property will not be set to true.)

For example, to define this, the SyncActiveStateAttribute must be specified in the child view or view model, like this:

[SyncActiveState]
public class MyViewModel : NotificationObject, IActiveAware
{
   (...)
}

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

rumzeus wrote Mar 30, 2012 at 12:51 PM

Hi,
That sounds great. I just upgraded to Prism 4.1 to test this. Unfortunately it doesn't seem to work in my case.

Same as the first workaround that was posted here, it doesn't seem to keep IActiveAware.IsActive remaining false for subviews of TabControls during startup.

I have a TabControl region with regionScoped views, each of which has a subregion with an activeaware (and SyncActiveState) subview. But after startup all these subviews are set to active, even though obviously only one tab is active.

DCherubini wrote Apr 19, 2012 at 5:05 PM

Hi rumzeus,

We were able to reproduce the behavior you are mentioning. Based on my understanding, it seems that, as the RegionActiveAwareBehavior executes its logic only when the ActiveViews collection is changed; if you add a sub view to a deactivated view, the state of the sub view will not be synchronized with the state of its parent view.

You can find more information about this and a possible workaround for this undesired behavior in the following blog post:
Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini