MasterDetail с Prism, как?

Я пытаюсь протестировать и пример с MasterDetail. Вы можете увидеть код в:

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

Мастер имеет 5 кнопок для доступа к 4 страницам с подробностями (Home, MainPage, ViewA, ViewB и ViewC).

Из ViewA с помощью 2 кнопок я могу загрузить ViewB и ViewC

Но я не могу сделать это, нажав кнопку в меню hambubrger, а затем загрузив соответствующую страницу с подробностями.

Это работает, только если я укажу абсолютный путь в CommandParameter в "PrismMasterDetailPage.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"
                  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 () возвращает: / PrismMasterDetailPage / NavigationPage / ViewA / NavigationPage? UseModalNavigation = true / ViewA.

Почему?

Если я нажимаю кнопку ViewA, ViewB или ViewC, ничего не отображается. Но метод OnNavigatedFrom () вызывается для каждого View * ViewModel.cs

Что случилось?

Спасибо!!


person José Ramón Arias    schedule 14.12.2019    source источник
comment
У вас вопрос, почему вы должны использовать PrismMasterDetailPage, чтобы основные детали были видны после навигации (например, меню гамбургера и т. д.)?   -  person JH_Dev    schedule 17.12.2019
comment
нет, у меня вопрос, почему работает, только если я укажу абсолютный путь в CommandParameter.   -  person José Ramón Arias    schedule 18.12.2019
comment
Я добавляю пример в конце своего вопроса.   -  person José Ramón Arias    schedule 18.12.2019


Ответы (2)


Первое, что вам нужно сделать, это понять, откуда вы осуществляете навигацию. Навигация в Xamarin.Forms очень зависит от того, откуда вы переходите. Помните, что без Prism вы бы сделали что-то вроде этого:

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());
person Dan Siegel    schedule 26.12.2019

Большое спасибо, Дэн Сигел! (@ Дэн С.)

Я только что видел ваш комментарий месяц назад, извините.

Я был новичком в C #, Xamarin и Prism, и я все еще новичок, но меньше :-)

Я многому научился и протестировал за последние недели, и я лучше понимаю концепции.

Прочитав вас, я знаю, что ../{path} действителен только с NavigationPage.

Более того, у меня была одна проблема, заключающаяся в том, что я проверял значение «_navigationService.GetNavigationUriPath ()» внутри метода OnNavigatedTo, и, как я прочитал позже, в этот момент UriPath не является настоящим окончательным UriPath.

В моем коде я написал:

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

Я переместил вызов GetNavigationUriPath () в другой метод, и результаты оказались такими, как я ожидал.

Спасибо!!

person José Ramón Arias    schedule 26.01.2020