У меня два экрана.
На первом - два Entries и кнопка «Сохранить», на втором - два Labels.
Оба имеют соответствующий связанный ViewModels.
например 1-й XAML:
<Entry x:Name = "Entry1" Text = "{Binding Entry1}"/>
<Button Command = "{Binding SaveCommand}" Text = "Save"/>
1-й ViewModel:
class Screen1ViewModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private string entry1;
public string Entry1;
{
get { return entry1; }
set
{
entry1= value;
PropertyChanged(this, new PropertyChangedEventArgs("Entry1"));
}
}
//similar code for Entry2
public ICommand SaveCommand { protected set; get; }
public Screen1ViewModel()
{
SaveCommand = new Command(OnSubmit);
}
public void OnSubmit()
{
//I guess here I supposed to transfer data from 1st screen to 2nd
}
}
Есть ли простой способ получить строки из записей 1-го экрана и передать их меткам 2-го экрана с помощью ViewModels?
@Alex, пожалуйста, взгляните на мой обновленный ответ, я добавил пояснение к своему коду, надеюсь, это поможет вам.





Я реализовал для вас очень упрощенный образец. Конечно, это не лучшая реализация для следующих действий:
((testApp.App)App.Current).MainPage.Navigation
Лучший способ реализовать навигацию - использовать службу навигации, как в следующей статье: https://mallibone.com/post/a-simple-navigation-service-for-xamarinforms
Это лучше, поскольку в этом случае ваша модель просмотра ничего не знает о страницах, она знает только строковый ключ страницы. Также легче понять код и отладить его, поскольку есть центральная точка вызова.
Также доступен набор инструментов MVVM light. В следующей статье показано, как использовать его функции и реализовать навигацию: https://mobileprogrammerblog.wordpress.com/2017/01/21/xamarin-forms-with-mvvm-light/
Служба обмена сообщениями - это худшее, что я могу порекомендовать в отношении навигации, так как код сложно понять, а отладка - настоящий беспорядок. Разъединяя код, вы делаете зависимые вещи независимыми, и новые люди не могут понять, как работает код. Обмен сообщениями хорош, когда вы передаете события из внутренних моделей представления в модель представления корневой страницы или из модели представления в представление или на страницу, но он не подходит для задачи навигации.
Мой простой образец можно найти ниже: Код приложения:
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;
}
}
}
Если вы не хотите, чтобы эти модели представления были связаны или имели отношения друг с другом, вам может потребоваться какой-то агрегатор событий или механизм обмена сообщениями (pub-sub). Xamarin Forms поставляется с готовой службой обмена сообщениями под названием Центр обмена сообщениями для достижения этой цели.
Какую структуру MVVM вы используете?