Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prism NavigationService get previous view name

Currently I'm implementing a Screen indicating wheater a module is not existing or still in development.

enter image description here

The Back Button has the following code:

 regionNavigationService.Journal.GoBack();

This is working as expected. But the user is not coming from the Home Screen. So I need to access the View Name from the last Entry in Navigation Journal.

Example: User is coming from Settings Screen => The text should display "Back to Settings Screen"

like image 577
Johannes Wanzek Avatar asked Dec 09 '22 06:12

Johannes Wanzek


1 Answers

Assuming the view name you are looking for is when you do new Uri("Main", UriKind.Relative) that you would want the word Main as the view name.

The forward and backward stacks in the RegionNavigationJournal are private. You could use reflection to get access to it.

var journal = regionNavigationService.Journal as RegionNavigationJournal;
if (journal != null)
{
    var stack =
        (Stack<IRegionNavigationJournalEntry>)
        typeof (RegionNavigationJournal).GetField("backStack",
                                                  BindingFlags.NonPublic | BindingFlags.Instance)
                                        .GetValue(journal);

    var name = stack.Peek().Uri.OriginalString;
}

Or a better way is to implement your own IRegionNavigationJournal that is a wrapper around it. This is using Unity to constructor inject the default RegionNavigationJournal if using MEF you might need to put the ImportingConstructorAttribute on it.

public class RegionNavigationJournalWrapper : IRegionNavigationJournal
{

    private readonly IRegionNavigationJournal _regionNavigationJournal;
    private readonly Stack<Uri> _backStack = new Stack<Uri>();

    // Constructor inject prism default RegionNavigationJournal to wrap
    public RegionNavigationJournalWrapper(RegionNavigationJournal regionNavigationJournal)
    {
        _regionNavigationJournal = regionNavigationJournal;
    }

    public string PreviousViewName
    {
        get
        {
            if (_backStack.Count > 0)
            {
                return _backStack.Peek().OriginalString;
            }
            return String.Empty;
        }
    }

    public bool CanGoBack
    {
        get { return _regionNavigationJournal.CanGoBack; }
    }

    public bool CanGoForward
    {
        get { return _regionNavigationJournal.CanGoForward; }
    }

    public void Clear()
    {
        _backStack.Clear();
        _regionNavigationJournal.Clear();
    }

    public IRegionNavigationJournalEntry CurrentEntry
    {
        get { return _regionNavigationJournal.CurrentEntry; }
    }

    public void GoBack()
    {
        // Save current entry
        var currentEntry = CurrentEntry;
        // try and go back
        _regionNavigationJournal.GoBack();
        // if currententry isn't equal to previous entry then we moved back
        if (CurrentEntry != currentEntry)
        {
            _backStack.Pop();
        }
    }

    public void GoForward()
    {
        // Save current entry
        var currentEntry = CurrentEntry;
        // try and go forward
        _regionNavigationJournal.GoForward();
        // if currententry isn't equal to previous entry then we moved forward
        if (currentEntry != null && CurrentEntry != currentEntry)
        {
            _backStack.Push(currentEntry.Uri);
        }
    }

    public INavigateAsync NavigationTarget
    {
        get { return _regionNavigationJournal.NavigationTarget; }
        set { _regionNavigationJournal.NavigationTarget = value; }
    }

    public void RecordNavigation(IRegionNavigationJournalEntry entry)
    {
        var currentEntry = CurrentEntry;
        _regionNavigationJournal.RecordNavigation(entry);
        // if currententry isn't equal to previous entry then we moved forward
        if (currentEntry != null && CurrentEntry == entry)
        {
            _backStack.Push(currentEntry.Uri);
        }
    }
}

If using unity in your Prism Bootstrapper you will need to replace the default registration of the IRegionNavigationJournal

protected override void ConfigureContainer()
{
    this.RegisterTypeIfMissing(typeof(IRegionNavigationJournal), typeof(RegionNavigationJournalWrapper), false);

    base.ConfigureContainer();
}

If using MEF you will need to put the ExportAttribute on top of the RegionNavigationJournalWrapper

[Export(typeof(IRegionNavigationJournal))]

You can see http://msdn.microsoft.com/en-us/library/gg430866%28v=pandp.40%29.aspx for more information on replacing their default implementation with your own. Once you have the wrapper you will still need to cast it as RegionNavigationJournalWrapper to get access to the PreviousViewName so still not perfect or create an interface that RegionNavigationJournalWrapper also implements to cast to that to get you access to the PreviousViewName

like image 152
CharlesNRice Avatar answered Dec 11 '22 07:12

CharlesNRice