【问题标题】:Wpf Prism Region NavigationWpf 棱镜区域导航
【发布时间】:2017-05-24 14:44:08
【问题描述】:

我一直在尝试让基于视图的导航使用 Prism 和区域来工作。我尝试浏览 MSDN 上的文档,但由于某种原因我无法让它工作,而且我不知道我做错了什么。所以这就是我到目前为止得到的:

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);
    }
}

旁注:我遵循的众多教程之一让我使用了导航方法,我需要它吗?我使用 MainShellViewModel 作为启动时注入的主视图。

DashboardViewModel.cs:(包含错误)

{
    //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?
    }

这里是我注册我的容器/视图等的地方。

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
}

所以基本上我只是希望能够通过单击按钮从仪表板(这是我当前的启动视图)转到在我的容器中注册的任何其他视图。

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"/>

但是,当我尝试让我的区域采用其他视图时,我不断收到错误消息。我这样做的方式是使用我的 DashboardViewModel,并创建另一个名为 _regionManager 的 IRegionManager,然后执行 RequestNavigation。在我运行它并按下应该将我链接到下一个视图的按钮之前,我没有收到任何错误。

任何帮助将不胜感激!

谢谢!

【问题讨论】:

  • 您能否展示仪表板 VM 代码的相关部分,即您在哪里创建 IRegionManager 以及在哪里调用它的 RequestNavigation() 方法?另外,您能否提供您看到的错误消息的详细信息?仔细检查一下,您应该将 IRegionManager 注入您的仪表板 VM(就像您使用主 VM 一样),并且 IRegionManager 必须在您的引导程序中注册为 singleton。
  • 是的,很抱歉。我刚刚添加了它。 xD

标签: c# wpf xaml prism


【解决方案1】:

不确定您是否已经得到答案,但我今天遇到了同样的事情。 Brian 的评论给了我必要的提示。

我在引导程序中有以下代码。这注册了两个视图以允许导航到它们:

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");
    }
}

这给出了一个 MainWindow,它注册了 ViewA 和 ViewB。 要允许从 ViewA 上的按钮导航到 ViewB,需要在 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");
    }
}

在 XAML 表单 ViewA 中,您最不需要的当然是按钮本身:

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

【讨论】:

  • 是的,我得到了答案,谢谢你!我就是这样做的。
【解决方案2】:

查看示例 17、18 和 19。这应该有助于您朝着正确的方向前进:

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

【讨论】:

  • 查看示例并复制它们不断给我错误。我注意到他们都只有一个视图,那就是 MainWindow。好吧,我有一个 Mainshellll,在那个 shell 中是我注入的一个视图。当我按下视图内的按钮时,我试图让它在该外壳内显示另一个视图。我一直在尝试不同的变化,但仍然没有运气。有什么想法吗?
  • 您是否运行了示例?它有一个外壳,允许您在该区域中导航多个视图。您可以通过单击按钮轻松地在视图之间导航。您可能只是完全错过了整个概念。其实很简单。
  • 您所做的就是确保您的视图已注册导航,然后调用 IRegionManager.RequestNaviagte 就可以了。
  • 是的,我很可能想念它,我是比较新的哈哈。我仍然试图抓住我的头。这个问题,还有这个:codereview.stackexchange.com/questions/164109/… 是我目前得到的。所以当你说注册时,我认为这就是我的引导程序中容器的用途?
  • 查看我提供的示例并运行它们
猜你喜欢
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-10
  • 2012-03-16
相关资源
最近更新 更多