Eine Sache die ich immer mal wieder bei Kisoksystemen brauche, ist die Ermittlung eines Navigationsziels mit Prism. Das heißt, ich habe einen bestimmten Workflow und sobald von einer View in eine andere navigiert werden soll, muss ich noch ein paar Aktionen ausführen, falls die Zielansicht bestimmte Eigenschaften aufweist.

So etwas kann man beispielsweise wie im folgenden Snippet tun. Dabei wird der NavigationContext, wie er beispielsweise ConfirmNavigationRequest übergeben wird, für die Suche der View innerhalb all registrierter Views einer Region verwendet. Dies ist notwendig, weil zu dem Zeitpunkt wo beispielsweise ConfirmNavigationRequest aufgerufen wird, es sich bei der aktiven View ja noch immer um die handelt in deren ViewModel die Methode aufgerufen wurde. Ein einfaches region.ActiveViews, hilft also nicht weiter.

IRegion region = regionManager.Regions.FirstOrDefault(x => x.Name == regionName);
if (region == null))
{
   // Error handling für den Fall dass es die Region nicht gibt
}
var targetView = region.Views.FirstOrDefault(x => x.GetType().Name == navigationContext.Uri.OriginalString);
if (targetView != null)
{
   // behandlung des Targets
}

Wie kann man dies nun sinnvoll nutzen? In dem man beispielsweise wichtige Views (oder ViewModels) mit einem bestimmten Interface versieht um so zusätzlich Informationen über deren Position im Workflow oder Status mit zu geben.

public interface IWorkflowModule
{
   bool IsMainWorkflow { get; }
}

Diesen kann man dann zum Beispiel in ConfirmNavigationRequest nutzen um unter Umständen die Navigation zu stoppen. Im Beispiel geschieht dies, wenn es sich beim Ziel nicht um eine View aus dem Hauptworkflow handelt.

public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{
   bool canNavigate = false;
   IRegion region = regionManager.Regions.FirstOrDefault(x => x.Name == regionName);
   if (region == null))
   {
      // Error handling für den Fall dass es die Region nicht gibt
   }
   var targetView = region.Views.FirstOrDefault(x => x.GetType().Name == navigationContext.Uri.OriginalString) as IWorkflowModule;
   if (targetView != null && targetView.IsMainWorkflow )
   {
       canNavigate = true;
   }
   continuationCallback(canNavigate);
}