📜  MVVM –连接视图(1)

📅  最后修改于: 2023-12-03 15:03:04.242000             🧑  作者: Mango

MVVM – 连接视图

MVVM(Model-View-ViewModel)是一种设计模式,用于构建用户界面。它将UI分为视图(View)和视图模型(ViewModel)两个部分,并通过数据绑定连接它们。MVVM可使UI开发更加易于测试和维护。

1. 概述

在MVVM中,视图(View)是用户界面的部分。它包含UI元素,如按钮、文本框和复选框。视图负责将用户输入转换为对应的命令和事件,并将数据传递到下层的视图模型。

视图模型(ViewModel)是视图模型层(View Model Layer)的代表。它包含业务逻辑和数据处理的核心代码,并通过数据绑定将其与视图相连。视图模型接收来自视图的数据请求和用户事件,并从模型层(Model Layer)中获取数据,通过数据绑定将数据返回到视图。视图模型旨在解耦视图和模型层之间的代码。

模型层(Model Layer)是应用程序业务逻辑的核心部分。它包括数据和数据访问逻辑。模型层通常包含数据访问对象(Data Access Object)和数据转换对象(Data Transfer Object)等形式,用于保持数据提供和消费之间的解耦,并支持应用程序的扩展和修改。

在MVVM中,将数据绑定与视图模型模式相结合可以提高代码质量和可维护性,并降低UI开发的复杂性。在许多情况下,MVVM都是最佳选择。

2. 视图(View)

视图(View)是用户界面的部分,可用于显示数据和处理用户输入。视图通常包含一个或多个绑定到视图模型的UI元素。数据绑定将视图与视图模型相连。

视图的主要工作是:

  • 展示数据和UI元素
  • 处理用户输入和事件
  • 数据验证和格式化

视图中的代码应该很少,因为修改代码时需要更改UI元素。

下面是一个简单的WPF视图实现代码:

<Window x:Class="MyApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="My Application"
    Width="800" Height="600"
    DataContext="{Binding Main, Source={StaticResource Locator}}">

   <Grid>
      <TextBlock Text="{Binding WelcomeText}" />
      <Button Content="Say Hello" Command="{Binding SayHelloCommand}" />
   </Grid>

</Window>

在此代码中,我们可以看到WPF视图的基本架构,文本块和按钮内容都是由View Model的WelcomeText属性和SayHelloCommand属性驱动。

3. 视图模型(ViewModel)

视图模型(ViewModel)是MVVM中的核心,它是将应用程序逻辑与视图分离的桥梁。视图模型通过维护视图状态和驱动UI中发生的事件来通信。视图模型层一般负责:

  • 实现界面的逻辑和数据,
  • 与模型进行数据交互,
  • 处理视图事件和命令处理,

视图模型与视图之间通信的机制是数据绑定。WPF支持多种类型的数据绑定,包括单向绑定、双向绑定和一次性绑定。

下面是一个.NET Core应用程序中的视图模型代码:

public class MainViewModel : BaseViewModel
{
    private string _welcomeText = "Welcome to my application!";
    public string WelcomeText
    {
        get => _welcomeText;
        set => Set(ref _welcomeText, value);
    }

    private RelayCommand _sayHelloCommand;
    public ICommand SayHelloCommand
    {
        get
        {
            if (_sayHelloCommand == null)
            {
                _sayHelloCommand = new RelayCommand(
                    () => WelcomeText = "Hello, World!",
                    () => true);
            }
            return _sayHelloCommand;
        }
    }
}

在此代码中,我们可以看到.NET Core应用程序中的ViewModel示例。BaseViewModel类,为所有视图模型提供通用基础设施。视图模型类实现与属性绑定的混合属性及用于注入到属性或方法中的命令。

4. 模型层(Model Layer)

然而,拥有这样良好的分离,并不保证我们获得易于扩展和测试的代码。这就是模型层(Model Layer)发挥作用的地方。为了将视图模型中的逻辑与数据访问分离开,我们需要使用处理视图模型与数据访问对象之间的抽象。这就是模型层所做的事情。

模型层包括以下组件:

  • 数据访问对象(Data Access Object):它用于与数据源通信并提供上层应用程序所需的数据访问。
  • 数据转换对象(Data Transfer Object): 对数据进行格式化、验证和转换。

下面是一个.NET Core应用程序中数据访问对象的示例:

public interface IDataService
{
    Task<string> GetWelcomeAsync();
}

public class DataService : IDataService
{
    public async Task<string> GetWelcomeAsync()
    {
        // fetch welcome data from a data source
        // return a welcome message
        return await Task.FromResult("Welcome to my application from the server!");
    }
}

在此代码中,我们可以看到.NET Core应用程序数据访问对象的一个示例。IDataSvcie定义了描述模型层面向的数据的契约。DataService实现了这个接口,从数据源中获取应用程序需要的数据。

5. ViewModelLocator

作为一个应用程序开发者,我们需要要做的是把所有这些部分组和起来。这就是ViewModelLocator的作用。

ViewModelLocator的主要责任是为WPF应用程序的所有视图和视图模型创建单例,并确保它们之间的实现和引用关系为正确。下面是一个典型的ViewModelLocator实现:

public class ViewModelLocator
{
    private static MainViewModel _main;

    static ViewModelLocator()
    {
        if (ViewModelBase.IsInDesignModeStatic)
        {
            // create design time view services and models
            _main = new MainViewModel(new DesignDataService());
        }
        else
        {
            // create run time view services and models
            _main = new MainViewModel(new DataService());
        }
    }

    public static MainViewModel Main => _main;

    public static void Cleanup()
    {
        // TODO Clear ViewModels
    }
}

在此代码中,我们可以看到ViewModelLocator用于创建单件视图模型的一个示例,MainViewModel是在其构造函数中使用IDataService进行了创建。

结论

MVVM是一种表现模型和视图之间的分离,并提供了一种充分利用数据绑定技术的方法。MVVM被认为是一种非常优秀的解决方案,因为它的优点很多,例如代码复用性高,保持UI代码分离并且代码的测试和维护都变得容易了很多。在对数据驱动应用程序进行设计和开发时,MVVM是一个非常不错的选择。