I was facing an issue where I want to retrieve existing/active ViewModels from the Prism runtime.

Here's the code I've done to achieve it:

public class ViewModelFinder
  readonly IRegionManager _RegionManager;
  readonly IContainer _Container;
  public ViewModelFinder(IContainer container, IRegionManager regionManager)
    _RegionManager = regionManager;
    _Container = container;

  public TViewModel FindOrResolve<TViewModel>()
    where TViewModel : class =>
    Find<TViewModel>() ?? _Container.Resolve<TViewModel>();

  /// <summary>
  /// Locates an existing VM in the entire region manager.
  /// </summary>
  public TViewModel Find<TViewModel>() => (TViewModel)Find(typeof(TViewModel));
  public object Find(Type viewModelType)
    var shellContext = Application.Current.MainWindow.DataContext;
    if (shellContext != null && viewModelType.IsAssignableFrom(shellContext.GetType()))
      return shellContext;

    foreach (var region in _RegionManager.Regions)
      var viewModel = Find(region, viewModelType);
      if (viewModel != null)
        return viewModel;
    return null;

  /// <summary>
  /// Locates an existing VM in the specified region.
  /// </summary>                                     
  public TViewModel Find<TViewModel>(IRegion region) => 
  (TViewModel)Find(region, typeof(TViewModel));
  public object Find(IRegion region, Type viewModelType)
    foreach (var view in region.Views.OfType<FrameworkElement>())
      if (view.DataContext != null &&
        return view.DataContext;
    return null;

It's intended to be used from any VM, by adding a ViewModelFinder to its constructor to be resolved by the IoC (in my case DryIoc).

When requesting for a VM, it will check for the Shell, then iterate over all views in all regions until it finds the desired VM.

Would love to hear about any better ways to achieve this.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.