在 Xamarin.Forms 项目中实现 MVVM

Posted

技术标签:

【中文标题】在 Xamarin.Forms 项目中实现 MVVM【英文标题】:Implementing MVVM in Xamarin.Forms project 【发布时间】:2015-09-08 17:03:44 【问题描述】:

我一直在使用 Xamarin.Forms,并制作了一个简单的“Hello World”类型的项目。我一直在尝试将同一个项目转换为 MVVM 类型的项目,只是为了感受一下。但是,我在决定我的模型应该是什么时遇到了麻烦。以下是我的项目目前的样子:

视图/MainView.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="TestGround.MainView">
        <ContentPage.Content>
            <StackLayout VerticalOptions="Center">
                <Label
                    Text="Binding Greeting"
                    VerticalOptions="Center"
                    HorizontalOptions="Center"
                />
                <Entry
                    Text="Binding Name"
                />
                <Button
                    Text="Enter"
                    Command="Binding SayHelloCommand"
                />
            </StackLayout>
        </ContentPage.Content>
</ContentPage>

视图/MainView.xaml.cs

using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace TestGround

    public partial class MainView : ContentPage
    
        public MainView ()
        
            InitializeComponent ();
            this.BindingContext = new MainViewModel();
        

    

ViewModels/MainViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;


namespace TestGround

    public class MainViewModel :INotifyPropertyChanged
    
        private string _greeting; //backing field for Greeting

        public string Greeting //implementation for Greeting method
         
            get  return _greeting;  

            set 
             
                _greeting = value;
                OnPropertyChanged ("Greeting"); //Notify view that change has taken place

            
        

        public string Name  get; set;  //Name method for Entry field, completely useless

        public ICommand SayHelloCommand  get; set;  //ICommand binds to buttons in XAML

        public void SayHello() //Need a regular method to add to ICommand
        
            Greeting = "Hello " + Name;
        

        public MainViewModel ()
        
            Greeting = "Its alive!";
            Name = "Enter name";

            SayHelloCommand = new Command(SayHello); //Regular command added to ICommand
        



        #region PropertyChangedRegion

        public void OnPropertyChanged (string propertyName)
        
            if (PropertyChanged != null)
                PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
        

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    

我有一个空的 Models 文件夹,我对 MVVM 结构的了解不足以决定我的 Models 应该是什么。我在想我应该在 Model 中声明我的方法并在 ViewModel 中实现它们,但我不确定。

谁能告诉我代码的哪些部分是模型?

【问题讨论】:

【参考方案1】:

在您发布的示例中,模型将是您设置GreetingName 的字符串。如果您的示例变得更高级,您最终可能会得到一个带有 Name 属性的 Person 模型对象,该属性来自数据库或 Web 服务等外部来源,

视图模型将负责检索Person 模型对象,可能是GetPerson(),并设置Name = Person.Name

表单移动 CRM 示例 models 和 view models。

“所以任何与 View 交互的东西都会进入 视图模型?所以我可以把 Greeting 和 Name 属性放在我的 模型,并让它们在 ViewModel 中初始化以显示在 查看?”

一般情况下,您可能只拥有不需要与视图模型交互的视图关注点。认为视图模型具有视图的无头表示。如果您有一个用于登录的视图模型,它可能具有UsernamePassword 属性和用于登录的Login 方法。当用户单击Login 按钮时,视图模型将验证Username 和@ 987654335@ 然后根据某些服务对用户进行身份验证。此时可以绑定视图以允许用户登录。也可以编写一个测试来测试使用相同视图模型的登录过程。

【讨论】:

那么我会在模型中声明像 _greeting 这样的支持字段吗?然后在我的 ViewModel 中实现 Greeting 方法? 另外,所以基本上我的模型将包含类,而我的视图模型将包含上述类的对象? 通常是的,模型是视图模型显示或处理的某些状态或数据的表示。视图模型是位于视图和模型之间的东西。它是视图和数据之间的交通警察。 视图模型具有 Greeting 属性,但如果有意义,模型也可以具有 Greeting 属性。 那么任何与 View 交互的东西都会进入 ViewModel 吗?所以我可以将 Greeting 和 Name 属性放在我的模型中,并在 ViewModel 中初始化它们以显示在 View 中?

以上是关于在 Xamarin.Forms 项目中实现 MVVM的主要内容,如果未能解决你的问题,请参考以下文章

如何使用依赖注入在 Xamarin.Forms 中实现 Flyoutnavigation

如何在 Xamarin Forms 中实现标记聚类(谷歌地图)

使用 Prism 在 Xamarin Forms 的后台服务中实现依赖注入

无法在 Xamarin.Forms 中实现导航

如何在 Xamarin Forms 中实现 CrossPushNotification 插件?

Xamarin.Forms中实现CheckBox控件