Access view model after view is closed
Good or not one of the scenario users need to support is to be able to use a
ViewModel
after the hosting View
is closed. A typical sample is the following:var view = viewResolver.GetView<MySampleView>();
view.ShowDialog();
var viewModel = conventions.GetViewDataContext(view, ViewDataContextSearchBehavior.LocalOnly);
//access some properties of the view model instance
The above snippet will fail with a null reference exception due to the fact that the view model instance will be null. The underlying reason is that as soon as the hosting view is closed:
- the
ViewModel
is detached from itsView
; - Both components are released through the
IReleaseComponents
service, causing disposition of disposable instances if supported;
The above is by design.
GetViewDataContext
will return a null reference in the above scenario. A first approach, as a workaround, can be the following:var view = viewResolver.GetView<MySampleView>();
var viewModel = conventions.GetViewDataContext( view, ViewDataContextSearchBehavior.LocalOnly );
view.ShowDialog();
//access here some properties of the view model instance
We simply retrieve a reference to the
ViewModel
before the view is closed and we use it later. What can happen is that accessing one of the ViewModel properties an ObjectDisposedException
is thrown because the AbstractViewModel
base class knows that the ViewModel
instance was released and disposed.The definitive solution is to override the automatic release behavior decorating the
View
class with the ViewManualReleaseAttribute
and changing our code as follows:var view = viewResolver.GetView<MySampleView>();
view.ShowDialog();
var viewModel = conventions.GetViewDataContext(view, ViewDataContextSearchBehavior.LocalOnly);
//access here some properties of the view model instance
conventions.ViewReleaseHandler(view, ViewReleaseBehavior.Force);
Once
MySampleView
is decorated with the ViewManualReleaseAttribute
it won't be released anymore automatically and the ViewModel
won't be detached, once we have finished using the ViewModel
instance we ask to the conventions to force the release of the View
and ViewModel
using the ViewReleaseHandler
convention and the Force
enumeration value to override the default behavior.