Wpf Prism 区域导航
Wpf Prism Region Navigation
我一直在尝试使用 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);
}
}
旁注:我遵循的众多教程之一让我放入了 Navigate 方法,我需要它吗?我正在使用 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?
}
这是我注册 containers/views 等的地方
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。在我 运行 它并按下应该 link 我进入下一个视图的按钮之前,我没有任何错误。
如有任何帮助,我们将不胜感激!
谢谢!
查看示例 17、18 和 19。这应该有助于您朝着正确的方向前进:
不确定您是否已经得到答案,但我今天 运行 遇到了同样的问题。 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}"/>
我一直在尝试使用 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);
}
}
旁注:我遵循的众多教程之一让我放入了 Navigate 方法,我需要它吗?我正在使用 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?
}
这是我注册 containers/views 等的地方
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。在我 运行 它并按下应该 link 我进入下一个视图的按钮之前,我没有任何错误。
如有任何帮助,我们将不胜感激!
谢谢!
查看示例 17、18 和 19。这应该有助于您朝着正确的方向前进:
不确定您是否已经得到答案,但我今天 运行 遇到了同样的问题。 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}"/>