I am developing a Xamarin Forms app, which it uses Prism Forms for navigation, basing me in some guides like: bootstrap-series-xamarin-forms-in-prism-forms
The problem is that by pressing the buttons on the ListView in ShellMaster, which is used for browsing, nothing happens, and the debugger does not register any breakpoint of the Navigate method.
My Code:
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; }
}
}
What I want to achieve is to be able to navigate with the elements of the ListView and that by pressing them and the itemsSelected does not turn null so that they remain selected.
Appreciate your help.