c# - Xamarin.Forms 使用 MVVM 在屏幕之间传输数据
问题描述
我有两个屏幕。
第一个有两个Entries
和保存按钮,第二个有两个Labels
。
两者都有对应的 bind ViewModels
。
例如第一个XAML
:
<Entry x:Name="Entry1" Text="{Binding Entry1}"/>
<Button Command="{Binding SaveCommand}" Text="Save"/>
第一个视图模型:
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
}
}
有什么简单的方法可以从第一个屏幕条目中获取字符串并使用 ViewModels 将它们传递给第二个屏幕标签?
解决方案
我已经为您实现了非常简化的示例。当然,执行以下操作并不是最好的实现:
((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/
消息服务是我可以推荐的关于导航的最糟糕的事情,因为它很难理解代码并且调试是一团糟。通过解耦代码,您可以使依赖的事物独立,并且新人无法了解代码的工作原理。当您将事件从内部视图模型传递到根页面视图模型或从视图模型传递到视图或页面时,消息传递很好,但它不适合导航任务。
我的简单示例可以在下面找到: 应用程序代码:
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;
}
}
}
推荐阅读
- scala - 无法在 Windows 操作系统上的 IntelliJ 中运行 scalatest
- tensorflow - 自定义损失计算导致 RuntimeError: Attempting to capture an EagerTensor without building a function
- android - 使用 Intent.ACITON_CREATE_DOCUMENT 将 Sqlite 数据库导出到 Excel 文件
- c# - 如何从 rtf 文件中读取链接并通过 C# 将它们放入 csv?
- office-js - 当我单击 Outlook Web 插件 - js 中的发送按钮时,如何打开任务窗格
- excel - MS Word 与 MS Excel 上的 Visual Basic
- excel - 显示由 windows scheduler 启动的隐藏 Excel 实例
- c# - 如何在 C# 中正确获取 csv 文件头?相同的代码得到不同的结果
- python - Dialogflow:意图训练短语 - 如何包含拼写错误/非正式的单词
- java - 单击recyclerview上的项目时的多个数据