简体   繁体   中英

How to navigate between View with Prism 7.2?

I'm writing an application and I want to put navigation in it. This application is using WPF and I'm using Prism 7.2.0.1367.

So I created 2 views: a HomePage and a ModeFileAttente view.

I'm also using the MVVM pattern.

Here is my app.xaml.cs :

public partial class App : PrismApplication
{
    protected override Window CreateShell()
    {
        return Container.Resolve<V.HomePage>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    { 
        containerRegistry.RegisterDialog<V.HomePage, VM.HomePageViewModel>();
        containerRegistry.RegisterDialog<V.ModeFileAttente, VM.ModeFIleAttenteViewModel>();
    }

    protected override void ConfigureModuleCatalog(IModuleCatalog  moduleCatalog)
    {
        moduleCatalog.AddModule<Bootstrapper>();
    }
}

My HomePage.xaml :

<Window x:Class="TestWPF.View.HomePage"
    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"
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="True"
    mc:Ignorable="d"
    Title="HomePage" Height="347.667" Width="664">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="277*"/>
        <ColumnDefinition Width="16*"/>
    </Grid.ColumnDefinitions>

    <DockPanel Grid.ColumnSpan="2" Margin="0,0,0.333,-0.333">
        <Button Padding="0" DockPanel.Dock="Left" Content="Mode normal" Command="{Binding ClickCommand}" CommandParameter="ModeFileAttente"/>
        <Button Padding="0" DockPanel.Dock="Right" Content="Mode tournois" HorizontalAlignment="Stretch"/>
    </DockPanel>
    <ContentControl prism:RegionManager.RegionName="ContentRegion" Margin="5"  />
  </Grid>
</Window>

And this is the view model:

class HomePageViewModel : BindableBase, IDialogAware, INotifyPropertyChanged
{   

    #region Private region
    private readonly IRegionManager _regionManager;

    public event Action<IDialogResult> RequestClose;
    #endregion

    public DelegateCommand<string> ClickCommand { get; private set; }



    public string Title => throw new NotImplementedException();

    public HomePageViewModel(IRegionManager regionManager)
    {
        _regionManager = regionManager;
        ClickCommand = new DelegateCommand<string>(ExecuteClickCommand);
    }

    private void ExecuteClickCommand(string path) {
        _regionManager.RequestNavigate("ContentRegion", "FileAttente");
    }

    public bool CanCloseDialog()
    {
        throw new NotImplementedException();
    }

    public void OnDialogClosed()
    {
        throw new NotImplementedException();
    }

    public void OnDialogOpened(IDialogParameters parameters)
    {
        throw new NotImplementedException();
    }
}

I also got a Bootstrapper class:

public class Bootstrapper : IModule
{
    public void OnInitialized(IContainerProvider containerProvider)
    {
    }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<ModeFileAttente>();
    }
}

My MVVM pattern work's well, but when I want to navigate between my "HomePage" and my "ModeFileAttente" view, nothing happens except a "System.Object" on my view.

I already search what could be the problem, but I didn't something that resolve my issue.

Did someone still got this error with this version of prism?

PS: my 2 view are in a "View" folder, same for the view model in a ViewModel folder

I believe you should register view with region on initialize. try the below code

public class Bootstrapper : IModule
{
     public void OnInitialized(IContainerProvider containerProvider)
     {
        _regionManager.RegisterViewWithRegion("RegionName", typeof(View));
        _regionManager.RegisterViewWithRegion("RegionName", typeof(View2));
     }
}

Now you can use

_regionManager.RequestNavigate("RegionName", "View"); 

Or

_regionManager.RequestNavigate("RegionName", "View2"); 

Update

If we use prism then there should be a dependency injection framework associated to it for example MEF or Unity for my project I am using Prism.Unity.Wpf if you are using Unity then you can ask your dependency injector to inject RegionManager by adding a constructor which will be injected by a IRegionManager see below

    readonly IRegionManager _regionManager;
    public Bootstrapper(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

When you Inject IRegionManager to the constructor Unity know to provide same instance all the time as it is maintained in Unity so no need to worry about using the same instance of IRegionManager elsewhere.

when we use prism:RegionManager.RegionName="ContentRegion" in XAML we are actually keeping a place holder to say Prism that there is a region which will be filled by any VIEW at some point look for it.

This is my understanding. Let me know if you find this useful Thanks.

"FileAttente" should be "ModeFileAttente":

 _regionManager.RequestNavigate("ContentRegion", "ModeFileAttente");

There is no "FileAttente" view registered for navigation.

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