我正在开发Xamarin Forms应用程序,该应用程序使用Prism Forms进行导航,并基于以下一些指南进行操作: bootstrap-series-xamarin-forms-in-prism-forms
问题在于,通过按下ShellMaster中用于浏览的ListView上的按钮,什么也不会发生,并且调试器不会注册Navigate方法的任何断点。
我的代码:
App.xaml.cs
using Xamarin.Forms.Xaml;
using Prism.Unity;
using Prism.Ioc;
using Prism;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace MyNewApp
{
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected async override void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync(nameof(Views.Shell) + "/" + nameof(Views.AppShellNavigationPage) + "/" + nameof(Views.Pages.HomePage));
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// Register Shell
containerRegistry.RegisterForNavigation<Views.Shell>(nameof(Views.Shell));
// Register Navigation page
containerRegistry.RegisterForNavigation<Views.AppShellNavigationPage>(nameof(Views.AppShellNavigationPage));
// Register Pages
containerRegistry.RegisterForNavigation<Views.Pages.HomePage>(nameof(Views.Pages.HomePage));
containerRegistry.RegisterForNavigation<Views.Pages.PageA>(nameof(Views.Pages.PageA));
containerRegistry.RegisterForNavigation<Views.Pages.PageB>(nameof(Views.Pages.PageB));
containerRegistry.RegisterForNavigation<Views.Pages.PageC>(nameof(Views.Pages.PageC));
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
Shell.xaml
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyNewApp.Views.Shell"
xmlns:pages="clr-namespace:MyNewApp.Views">
<MasterDetailPage.Master>
<pages:ShellMaster x:Name="MasterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail/>
</MasterDetailPage>
Shell.xaml.cs
using Xamarin.Forms.Xaml;
using Prism.Navigation;
using Xamarin.Forms;
namespace MyNewApp.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Shell : MasterDetailPage
{
public Shell()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
}
}
public class AppShellNavigationPage : NavigationPage, INavigationPageOptions, IDestructible
{
public AppShellNavigationPage()
{
BarTextColor = Color.White;
BarBackgroundColor = Color.Accent;
}
public bool ClearNavigationStackOnNavigation
{
get { return false; }
}
public void Destroy()
{
}
}
}
ShellMaster.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyNewApp.Views.ShellMaster"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
Title="Master">
<StackLayout>
<ListView x:Name="MenuItemsListView"
SeparatorVisibility="None"
HasUnevenRows="true"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="15,10" HorizontalOptions="FillAndExpand">
<Label VerticalOptions="FillAndExpand" VerticalTextAlignment="Center" Text="{Binding Title}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
ShellMasterViewModel.cs
using System.Collections.ObjectModel;
using System.Collections.Generic;
using Prism.Navigation;
using MyNewApp.Models;
using Prism.Commands;
using Prism.Mvvm;
namespace MyNewApp.ViewModels
{
public class ShellMasterViewModel : BindableBase, INavigationAware
{
protected INavigationService _navigationService { get; }
public ObservableCollection<NavigationItem> MenuItems { get; set; }
private NavigationItem _selectedItem;
public NavigationItem SelectedItem
{
get
{
return _selectedItem;
}
set
{
SetProperty(ref _selectedItem, value);
if (_selectedItem == null)
{
return;
}
_navigationService.NavigateAsync(nameof(Views.Shell) + "/" + nameof(Views.AppShellNavigationPage) + "/" + nameof(Views.Pages.NoActiveProject));
}
}
public DelegateCommand<NavigationItem> SelectItemCommand { get; set; }
public ShellMasterViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
MenuItems = new ObservableCollection<NavigationItem>()
{
new NavigationItem { Title="HomePage", PageName = nameof(Views.Pages.HomePage)},
new NavigationItem { Title="PageA", PageName = nameof(Views.Pages.PageA)},
new NavigationItem { Title="PageB", PageName = nameof(Views.Pages.PageB)},
new NavigationItem { Title="PageC", PageName = nameof(Views.Pages.PageC)},
};
SelectItemCommand = new DelegateCommand<NavigationItem>((s) => Navigate(s));
}
public async void Navigate(NavigationItem selectedItem)
{
if (selectedItem != null)
{
await _navigationService.NavigateAsync(nameof(Views.Shell) + "/" + nameof(Views.AppShellNavigationPage) + "/" + selectedItem.PageName);
}
}
List<string> ModulePages()
{
return new List<string>()
{
nameof(Views.Pages.HomePage),
nameof(Views.Pages.PageA),
nameof(Views.Pages.PageB),
nameof(Views.Pages.PageC),
};
}
public void OnNavigatedFrom(NavigationParameters parameters)
{
}
public void OnNavigatedTo(NavigationParameters parameters)
{
}
public void OnNavigatingTo(NavigationParameters parameters)
{
}
}
}
NavigationItem.cs
namespace MyNewApp.Models
{
public class NavigationItem
{
public string Title { get; set; }
public string Icon { get; set; }
public string PageName { get; set; }
}
}
我想要实现的是能够导航ListView的元素,并且通过按下它们,itemsSelected不会变为null以便保持选中状态。
感谢您的帮助。
答案 0 :(得分:1)
不容易剖析您的样本,但我猜您的Navigate(NavigationItem selectedItem)
不正确。
它应该触发一次导航,以便PRISM可以将所选页面加载到MasterDetail设置的详细信息部分。
尝试:await _navigationService.NavigateAsync( nameof(Views.AppShellNavigationPage) + "/" + selectedItem.PageName);
作为参考,我曾经在自己的GitHub上的测试仓库中设置了相同的场景,也许可以进一步帮助您? https://github.com/Depechie/PRISMNavigation/blob/master/BasePageDemo.NetStandard/ViewModels/MDViewModel.cs