簡體   English   中英

Xamarin形式的棱鏡導航

[英]Prism Navigation in Xamarin Forms

我正在開發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,從而使它們保持選中狀態。

感謝您的幫助。

剖析樣本並不容易,但是我猜測您的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM