2
\$\begingroup\$

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 &&
      viewModelType.IsAssignableFrom(view.DataContext.GetType()))
        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.

\$\endgroup\$

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.