kaycee kaycee - 1 month ago 21
C# Question

Prism do not re-navigate to active view

I am using prism with WPF application.
I want to navigate to "SearchResultsView" on property change but only if the view is not the active view

this is my code:

public string SearchString
{
get { return _searchString; }
set
{
if (_searchString != value)
{
_searchString = value;

_regionManager.RequestNavigate(RegionNames.ContentRegion, "SearchResultsView");

OnPropertyChanged();
}
}
}


the first time the navigation occurs it's ok.
but then every time the searchString is changed it still re-navigates to the same active view.

i'm registering the view in the module Init() as follows:

_container.RegisterTypeForNavigation<SearchResultsView>();


since i am using MVVM i can't check for the active view just before the navigation like this:

var activeView = _regionManager.Regions[RegionNames.ContentRegion].ActiveViews.FirstOrDefault();


what is the correct code to do that ?
(asking for "SearchResultsView" instead of its type would satisfy)

Answer

The simplest solution is to just implement IRegionMemberLifetime in your SearchResultsView or ViewModel just like this:

public class SearchResultsViewModel : BindableBase, IRegionMemberLifetime
{
    // Stuff...

    public bool KeepAlive => false;
}

This will cause Prism to destroy the region content if it is navigated away from.


Otherwise you could implement INavigationAware to check if the search strings are different:

public string SearchString
{
    get { return _searchString; }
    set
    {
        if (_searchString != value)
        {
            _searchString = value;

            var navigationParams = new NavigationParameters {{ "searchString", _searchString }};
            _regionManager.RequestNavigate(RegionNames.ContentRegion, "SearchResultsView", navigationParams);

            OnPropertyChanged();
        }
    }
}

// --------------------------------------------------------------------

public class SearchResultsViewModel : BindableBase, INavigationAware
{
    private string _searchString;

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        _searchString = navigationContext.Parameters["searchString"] as string;
    }

    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
        var searchString = navigationContext.Parameters["searchString"] as string;
        return _searchString.Equals(searchString);
    }

    public void OnNavigatedFrom(NavigationContext navigationContext)
    {
        // Ignored
    }
}

This will tell Prism to create every time a new instance if the search string is different, otherwise it will display the existing one.

Warning: But this could result in a MemoryLeak, because you will probably create many instances of the view if the search string doesn't matches, so you would need to clean them up manually.

Comments