带 Prism 的 MasterDetail,怎么样?

MasterDetail with Prism, how to?

我正在尝试使用 MasterDetail 进行测试和示例。您可以在以下位置查看代码:

https://github.com/jrariasf/MD8/tree/master/MD8

Master 有 5 个按钮可以访问 4 个详细信息页面(Home、MainPage、ViewA、ViewB 和 ViewC)。

从 ViewA,使用 2 个按钮我可以加载 ViewB 和 ViewC

但我无法在汉堡包菜单中按下按钮然后加载足够的详细信息页面。

只有当我在 "PrismMasterDetailPage.xaml":

中的 CommandParameter 中放置一个绝对路径时它才有效
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
                  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                  xmlns:prism="http://prismlibrary.com"
                  prism:ViewModelLocator.AutowireViewModel="True"
                  x:Class="MD8.Views.PrismMasterDetailPage">

    <MasterDetailPage.Master>
        <ContentPage Title="Menu">
            <StackLayout Padding="20">
                <!-- TODO: // Update the Layout and add some real menu items  -->
                <Button Text="Home" Command="{Binding NavigateCommand}" CommandParameter="/PrismMasterDetailPage/NavigationPage/ViewA" />
            <Button Text="MainPage" Command="{Binding NavigateCommand}" CommandParameter="/NavigationPage/MainPage" />
            <Button Text="ViewA" Command="{Binding NavigateCommand}" CommandParameter="../ViewA" />
            <Button Text="ViewB" Command="{Binding NavigateCommand}" CommandParameter="./ViewB" />
            <Button Text="ViewC" Command="{Binding NavigateCommand}" CommandParameter="ViewC" />
            </StackLayout>
        </ContentPage>
    </MasterDetailPage.Master>

</MasterDetailPage>

然后,在"PrismMasterDetailPageViewModel.cs"

void ExecuteCommandName(string page)
{
    Console.WriteLine("PrismMasterDetailPageViewModel - ExecuteCommandName() Vamos a {0}", page);

    _navigationService.NavigateAsync(page);
}

如果我在“/PrismMasterDetailPage/NavigationPage/ViewA”,我需要做什么来卸载 ViewA 和加载 ViewB?

例如App.xaml.cs中的代码是:

await NavigationService.NavigateAsync("PrismMasterDetailPage/NavigationPage/ViewA");

然后,在 android 模拟器上执行应用程序,按下汉堡菜单按钮,结果与我预期的不一样。 按主页按钮,_navigationService.GetNavigationUriPath() returns: /PrismMasterDetailPage/NavigationPage/ViewA/NavigationPage?useModalNavigation=true/ViewA

为什么?

如果我按下按钮 ViewA 或 ViewB 或 ViewC,它不会显示任何内容。但是在每个 View*ViewModel.cs

上调用了 OnNavigatedFrom() 方法

怎么了?

谢谢!!

您需要做的第一件事就是了解您的导航起点。 Xamarin.Forms 中的导航在很大程度上取决于您从何处导航。请记住,如果没有棱镜,你会做这样的事情:

var mdp = new MyMasterDetailPage
{
    Detail = new NavigationPage(new ViewA)
};

为了使用 Prism 实现汉堡包菜单,您通常需要一个 MasterDetailPage 作为应用程序的主页。 Navigation Uri 中的下一段必须是 NavigationPage,下一页通常是 ContentPage。

<Button Text="Home" 
        Command="{Binding NavigateCommand}" 
        CommandParameter="/PrismMasterDetailPage/NavigationPage/ViewA" />

好的,请看第一个,这通常是您从 PrismApplication 导航时使用的内容,这就是它起作用的原因。

<Button Text="MainPage" 
        Command="{Binding NavigateCommand}" 
        CommandParameter="/NavigationPage/MainPage" />

看看这个,这真的很接近你想要的,除了你正在进行绝对导航,这意味着你正在重置 Application.MainPage。您实际需要的是相对 Uri,因为您是从 MasterDetailPage 导航的。

<Button Text="ViewA" 
        Command="{Binding NavigateCommand}" 
        CommandParameter="../ViewA" />

这是完全错误的,因为 ../{path} 仅在 NavigationPage 中受支持,而您在 MasterDetailPage 中...

<Button Text="ViewB" 
        Command="{Binding NavigateCommand}" 
        CommandParameter="./ViewB" />

Prism 完全不支持。

<Button Text="ViewC" 
        Command="{Binding NavigateCommand}" 
        CommandParameter="ViewC" />

这是将 MasterDetailPage.Detail 设置为:

mdp.Detail = new ViewC()

当然,正如我上面提到的,你需要它

mdp.Detail = new NavigationPage(new ViewC());

非常感谢丹·西格尔! (@Dan S.)

一个月前才看到你的评论,不好意思。

我是 C#、Xamarin 和 Prism 的新手,现在我仍然是新手,但更少了:-)

在过去的几周里,我学到了很多东西,也进行了很多测试,对概念的理解也更好了。

阅读后我知道 ../{path} 仅对 NavigationPage 有效。

此外,我遇到的一个问题是我在 OnNavigatedTo 方法中检查“_navigationService.GetNavigationUriPath()”的值,正如我稍后阅读的那样,那时 UriPath 不是真正的最终 UriPath。

在我的代码中我写道:

public void OnNavigatedTo(INavigationParameters parameters)
{
    Console.WriteLine("DEBUG - ViewAVM: We are in {0}",
            _navigationService.GetNavigationUriPath());
}

我将 GetNavigationUriPath() 调用移至另一个方法,结果如我所料。

谢谢!!