Detecting view model close

Topics: Prism v2 - WPF 4
Sep 3, 2010 at 3:35 PM

I am using Prism to create tab items in a tab control.  Each tab item can have multiple regions, and the views in each region can have regions of their own.  Each view has it's own view model.

In some of the view models I suscribe to events using the EventAggregator.  Although I realise that because there is a weak reference to these events, I would still like to unsubscribe from these events when a tab closes.  The idea of the events still being handled between the tab closing and the garbage collector running makes me uneasy.

Is there anyway for a view mode (or a view) to detect when it is being unloaded so that I can explicitly unsubscribe from the events? 

Thanks

Sep 3, 2010 at 5:46 PM
Edited Sep 3, 2010 at 6:01 PM

Hi,

As you mentioned it is not something necessary, since it will be disposed. But Prism could help you to achieve this scenario by using the concept of Region Behaviors. These are pluggable components that allow you to extend the region’s implementation. For more information about this topic, you could take a look at the following documentation section on MSDN:

As for how to unsubscribe your view model from these events, you could use the RegionActiveAwareBehavior that requires you to implement IActiveAware in your view. This region behavior is attached by default and it is responsible for notifying a view if it is active or inactive.  Therefore, you can be notified when a particular view is removed by implementing IActiveAware from your view. So, you could perform a particular action like the unsubscribe from these events. Your view code could look like the following:

public partial class DefaultViewC : UserControl, IActiveAware 
 {
     public DefaultViewC()
     {
         InitializeComponent();
     }

     private bool isActive = default(bool);
     public bool IsActive
     {
         get { return this.isActive; }
         set
         {
             this.isActive = value;
             //here you could send a flag that notifies that your view has been removed
             this.OnActiveChanged(EventArgs.Empty);
         }
     }
     public virtual void OnActiveChanged(EventArgs e)
     {
         if (this.IsActiveChanged != null)
             this.IsActiveChanged(this, e);
     }
     public event System.EventHandler IsActiveChanged;
 }

For more information about this topic, you could check the following documentation section on MSDN:

Please let me know if this helps.

Fernando Antivero
http://blogs.southworks.net/fantivero

Sep 6, 2010 at 8:47 AM

Hi,

Thank you for your suggestion - I have tried it out but face a problem.

Unfortunately IActiveAware gets set to false when the user switches from one tab to another.  I only want to know when the tab is closed as the events still need to be handled when the tab is open, even if it is not the active tab.

Is there any way to differentiate between the view being made inactive, and the view being closed?

Thanks

Sep 22, 2010 at 9:02 PM

Hi,

The RegionActiveAwareBehavior is also notifying you when a particular view is deactivated. In this particular case, I think that you could modify the Region class, so when the Remove method is called, you could raise an event.

Fernando Antivero
http://blogs.southworks.net/fantivero

 

Sep 29, 2010 at 10:50 AM

Hi,

I'm not sure what you mean by this - would this involve changing the Prism source?

Instead we have changed our application to use the event aggregator to publish an event when the tab is closed - our View Model base class listens for this event and performs any clean up neccessary.

I'm not sure if this is the best way of dealing with it - but it is working for us.

Thanks for your help

Matt

Sep 29, 2010 at 2:18 PM

Hi Matt,

Thanks for sharing this with the rest of the community, since users with similar scenarios could find this helpful. Nice to see that you found an approach that suites your scenario. It is recommendable to use the recommended approaches by the product team like event aggregator or others if possible.

But in some cases if you consider that it is necessary for achieving a particular scenario, a possible option could be to extend the Prism library.

Thanks again,

Fernando Antivero
http://blogs.southworks.net/fantivero