Jamie Kiefner
April 30, 2015

WPF: Clearing Data Context with MVVM Light

Jamie Kiefner

I recently ran into an issue with a WPF application that is a continuous operation Kiosk application. The users log in and are presented with a survey. If the Kiosk is ignored for a time period, a timeout occurs and the screen is reset. However, I discovered that when using MVVM light and View Model (context) injection, even though the view is disposed of, the view model is not. This presented itself when a second user was presented the survey after a timeout had occurred, the survey started on page two or wherever the previous user had left off.

Developer thinking
I tried multiple scenarios of inheriting IDisposable and disposing of the view manually. I also tried several ways of clearing the view’s internal context. It was after none of my efforts were successful, I realized that the context was being stored for re-use by the ServiceLocator and could not be disposed of by the view.

Wait a minute… Inversion of Control… The view should not be able to control the view model. It’s working exactly as designed.

How does it get there?

Normal MVVM Light injection takes place from a ViewModelLocator class that is declared as a resource in the App.xaml. There is plenty of documentation of MVVM Light framework on their website, so I won’t go into the details of setup. But, in a nutshell, the view has its context injected in the XAML page as an attribute like so:

DataContext="{Binding Source={StaticResource Locator}, Path=SurveyPage}"

The path corresponds to a method in the Locator class which returns an instance of the view model from the service locator if one exists or creates a new one if not present.

 public SurveyViewModel SurveyPage
        {
            get
            {
                return ServiceLocator.Current.GetInstance<SurveyViewModel>();
            }
        }

If an instance doesn’t exist, one is instantiated during the InitializeComponant() method of the view. However, here is where the problem arises. If you dispose or close the view in normal operations, WPF disposes all of its internal resources associated with the view, but the instance of the view model remains in the ServiceLocator container.

How to clear out the view model

After a fair amount of unsuccessful research on the Google box, necessity (panic?) presented a really simple solution. As one would expect, closing the view fires the build in Unloaded event. Here is our jump in point. Our Locator class is a static method, so the simplest solution was to add a method to unregister and re-register the view model. As I was happy to find out, this cleared the model from the container and registered a new version. Since the container did not have an instantiation of my view model after the unregister process, the next time my view ran through the InitializeComponent () method, Bingo! A new view model is instantiated and injected as context for the view. Here is the very simple method I created to remove the view model:

public static void UnRegisterSurveyViewModel()
        {
            SimpleIoc.Default.Unregister<SurveyViewModel>();
            SimpleIoc.Default.Register<SurveyViewModel>();
        }
And I simply call it from the unloaded event:
private void MyView_Unloaded(object sender, RoutedEventArgs e)
        {
            MvvmViewModelLocator.UnRegisterSurveyViewModel();
        }

7 Comments

  1. 7 Sarah P. 05 May
    "Locator class is a static method..." I wonder if the class & methods were not static, if it would have been correctly disposed of and unregistered when the instance of the view model is no longer needed or when its resources are disposed of since it would require being instantiated along with the objects using it? In other words, is the fact that its static what is allowing it to "hang around" because there is no enforced constraint of object instantiation?
  2. 6 natagolister 18 Feb
    Exceptionally well written! I will immediately snatch your rss as I can not in finding your email subscription hyperlink or e-newsletter service. Do you’ve any? Kindly allow me know so that I could subscribe.
  3. 5 Melissa 19 Feb
    @natagolister - Thank you very much, we are glad that you enjoyed the post.  We went ahead and subscribed you to the blog subscription which can be done from any blog page in the upper right hand corner.  Let us know if you have any other questions. 
  4. 4 RonaldSpok 04 Mar
    Very well written! I’ll immediately seize your rss as I can’t to find your email subscription hyperlink or newsletter service. Do you’ve any? Kindly allow me recognize in order that I could subscribe.
  5. 3 Melissa 04 Mar
    @RonaldSpok - Thank you very much, we are glad that you enjoyed the post.  We went ahead and subscribed you to the blog subscription which can be done from any blog page in the upper right hand corner.  Let us know if you have any other questions.
  6. 2 Cleidson 27 Jul
    You saved my life !!!!
  7. 1 Melissa 28 Jul
    @Cleidson  - Glad we could be of help!

Comment

  1. RadEditor - HTML WYSIWYG Editor. MS Word-like content editing experience thanks to a rich set of formatting tools, dropdowns, dialogs, system modules and built-in spell-check.
    RadEditor's components - toolbar, content area, modes and modules
       
    Toolbar's wrapper 
     
    Content area wrapper
    RadEditor's bottom area: Design, Html and Preview modes, Statistics module and resize handle.
    It contains RadEditor's Modes/views (HTML, Design and Preview), Statistics and Resizer
    Editor Mode buttonsStatistics moduleEditor resizer
      
    RadEditor's Modules - special tools used to provide extra information such as Tag Inspector, Real Time HTML Viewer, Tag Properties and other.
       

Subscribe to Our Blog

Get the latest blog posts sent right to your inbox so you never miss an informative post from Mercury.

 

Get Your Share On!

 

Tags