简体   繁体   中英

Wpf Prism Region Navigation

I've been trying to get view-based navigation to work using Prism and regions. I tried going through the documentation on MSDN, but for some reason I can't get it to work, and I don't know what I am doing wrong. So this is what I got so far:

MainShellViewModel.cs

//Private Variables
private readonly IRegionManager _regionManager;

//Public Variables
public DelegateCommand<string> NavigateCommand { get; set; }

//Functions and Methods
public MainShellViewModel(IRegionManager regionManager)
{
    //Region Manager
    _regionManager = regionManager;
    NavigateCommand = new DelegateCommand<string>(Navigate);
    Initialize();
}

public void Initialize()
{
    //Startup View
    _regionManager.RegisterViewWithRegion("ViewMainFrame", typeof(Views.Dashboard));
}

public void Navigate(string uri)
{
    //Navigation
    if(uri != null)
    {
        _regionManager.RequestNavigate("ViewMainFrame", uri);
    }
}

Side note: One of the many tutorials I followed had me put in that Navigate method, do I need it? I am using the MainShellViewModel as the Main view that is injected on startup.

DashboardViewModel.cs: (Contains the error)

{
    //Private Variables
    private bool _canExercise = true;

    //Public Variables
    public bool CanExercise()
    {
        return _canExercise;
    }

    RelayCommand _exerciseSelCommand;
    public ICommand ExerciseSelCommand
    {
        get
        {
            if (_exerciseSelCommand == null)
                _exerciseSelCommand = new RelayCommand(ExerciseSel, CanExercise);

            return _exerciseSelCommand;
        }
    }

    //Dashboard Functions and Methods
    IRegion _regionManager;

    private void ExerciseSel()
    {
        SoundPlayers.ButtonSound();
        _regionManager.RequestNavigate(new Uri("ExerciseView", UriKind.Relative)); //This gives me the error, it says it can't be nullable?
    }

Here is where I register my containers/views, etc.

Bootstrapper.cs:

protected override void ConfigureContainer()
{
    base.ConfigureContainer();
    #region Region Register Zone
    //register views here!
    Container.RegisterType(typeof(object), typeof(Views.LoginView), "LoginView");
    Container.RegisterType(typeof(object), typeof(Views.Dashboard), "Dashboard");
    Container.RegisterType(typeof(object), typeof(Views.ExerciseView), "SettingsView"); 
    Container.RegisterType(typeof(object), typeof(Views.ResultsView), "ResultsView");
    Container.RegisterType(typeof(object), typeof(Views.UserCreationView), "UserCreationView");
    #endregion
}

So basically I just want to be able to get from the Dashboard (Which is my current startup view) to any other view that's registered in my containers on a click of a button.

MainShell.xaml:

<Window x:Name="Shell" 
    x:Class="Equinox.Views.MainShell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:prism="http://www.codeplex.com/prism"
    prism:ViewModelLocator.AutoWireViewModel="True"
    Title="Equinox"
    FontFamily="Quicksand"
    Height="900" 
    Width="1500"
    SizeToContent="WidthAndHeight"
    ResizeMode="CanResize"
    Background="#EEF3F4"
    WindowStyle="SingleBorderWindow"
    Icon="/Equinox;component/favicon.ico"
    WindowStartupLocation="CenterScreen">

<!-- Main View Region -->

<ContentControl x:Name="ContentControlMain"
                prism:RegionManager.RegionName="ViewMainFrame" 
                Focusable="False"/>

However, I keep getting errors when I try to make my region take another view. The way I was doing it was by using my DashboardViewModel, and creating another IRegionManager named _regionManager , and doing the RequestNavigation. I got no errors until I ran it and pressed the button that should link me to the next view.

Any help would be appreciated!

Thanks!

Not sure if you got the answer already, but I was running into the same thing today. The comment from Brian gave me the necessary hint.

I have the following code in the bootstrapper. This registers the two views to allow navigation to them:

public class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void InitializeShell()
    {
        Application.Current.MainWindow.Show();
    }

    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        Container.RegisterTypeForNavigation<ViewA>("ViewA");
        Container.RegisterTypeForNavigation<ViewB>("ViewB");
    }
}

This gives a MainWindow, which registers ViewA and ViewB. To allow for navigation to ViewB from a button on ViewA, the following needs to be done in ViewAViewModel:

public class ViewAViewModel: BindableBase
{
    private readonly IRegionManager _regionManager;

    public ViewAViewModel(IRegionManager regionManager)
    {
        _regionManager = regionManager;

        ButtonCommand= new DelegateCommand(ButtonClicked);
    }        

    private void ButtonClicked()
    {
        _regionManager.RequestNavigate("ContentRegion", "ViewB");
    }
}

In the XAML form ViewA the last thing you need is of course the button itself:

<Button Content="Navigate" Command="{Binding ButtonCommand}"/>

Check out sampels 17, 18, and 19. This should help get you going in the right direction:

https://github.com/PrismLibrary/Prism-Samples-Wpf

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM