Я реализовал очень упрощенный пример для вас.
Конечно, это не лучшая реализация, чтобы делать следующее:
((testApp.App)App.Current).MainPage.Navigation
Лучший способ реализовать навигацию - использовать службу навигации, как в следующей статье:
https://mallibone.com/post/a-simple-navigation-service-for-xamarinforms
Это лучше, так как в этом случае ваша viewModel ничего не знает о страницах, она знает только строковый ключ страницы. Также легче понять код и отладить его, поскольку существует центральная точка вызова.
Существует также легкий инструментарий MVVM. В следующей статье показано, как использовать его возможности и реализовать навигацию:
https://mobileprogrammerblog.wordpress.com/2017/01/21/xamarin-forms-with-mvvm-light/
Служба обмена сообщениями - это худшая вещь, которую я могу порекомендовать в отношении навигации, поскольку трудно понять код, а отладка - это настоящий беспорядок. Развязывая код, вы делаете зависимые вещи независимыми, и новые люди не могут понять, как работает код. Обмен сообщениями полезен при передаче событий из внутренних viewModels в модель представления корневой страницы или из модели представления для просмотра или на страницу, но он не подходит для задачи навигации.
Мой простой пример можно найти ниже:
Код приложения:
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new Views.Page1());
}
Page1.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="testApp.Views.Page1"
xmlns:local="clr-namespace:testApp.Views;assemply=testApp">
<ContentPage.BindingContext>
<local:Page1ViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Entry Text="{Binding TextPropertyValue}" />
<Button Command="{Binding SaveCommand}" Text="Save"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Page1ViewModel:
using System;
using System.ComponentModel;
using System.Windows.Input;
namespace testApp.Views
{
public class Page1ViewModel:INotifyPropertyChanged
{
public Page1ViewModel()
{
SaveCommand = new Xamarin.Forms.Command(HandleAction);
}
async void HandleAction(object obj)
{
await ((testApp.App)App.Current).MainPage.Navigation.PushAsync(
new Page2()
{
BindingContext = new Page2ViewModel(TextPropertyValue)
});
}
string entry1;
public string TextPropertyValue
{
get
{
return entry1;
}
set
{
if (value!=entry1)
{
entry1 = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TextPropertyValue)));
}
}
}
public ICommand SaveCommand
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
Page2.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="testApp.Views.Page2">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding EntryValue}"/>
</StackLayout>
</ContentPage.Content>
Page2.xaml.cs
public partial class Page2 : ContentPage
{
public Page2()
{
InitializeComponent();
}
}
Page2ViewModel
using System;
namespace testApp.Views
{
public class Page2ViewModel
{
public Page2ViewModel(string entry)
{
EntryValue = entry;
}
public string EntryValue
{
get;
set;
}
}
}