Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在MVVM中,每个ViewModel是否只耦合到一个模型?_C#_Design Patterns_Mvvm - Fatal编程技术网

C# 在MVVM中,每个ViewModel是否只耦合到一个模型?

C# 在MVVM中,每个ViewModel是否只耦合到一个模型?,c#,design-patterns,mvvm,C#,Design Patterns,Mvvm,在MVVM实现中,每个ViewModel是否只耦合到一个模型 我试图在一个项目中实现MVVM模式,但我发现有时候,视图可能需要来自多个模型的信息 例如,对于用户档案视图,其用户档案视图模型可能需要来自用户帐户模型、用户档案设置模型、用户PostSDataModel等的信息 然而,在我读到的大多数关于MVVM的文章中,ViewModel通过依赖项注入只包含在一个模型上。因此构造函数只接受一个模型 当必须从多个模型获取信息时,视图模型将如何工作?或者,MVVM中是否会出现这种情况 PS:我没有使用棱

在MVVM实现中,每个
ViewModel
是否只耦合到一个
模型

我试图在一个项目中实现MVVM模式,但我发现有时候,
视图
可能需要来自多个
模型的信息

例如,对于
用户档案视图
,其
用户档案视图模型
可能需要来自
用户帐户模型
用户档案设置模型
用户PostSDataModel
等的信息

然而,在我读到的大多数关于MVVM的文章中,ViewModel通过依赖项注入只包含在一个模型上。因此构造函数只接受一个模型

当必须从多个
模型
获取信息时,
视图模型
将如何工作?或者,MVVM中是否会出现这种情况


PS:我没有使用棱镜或统一框架。我正在尝试将类似的模式实现到一个不使用Prism或Unity的项目中。这就是为什么我需要确切地了解其中一些东西是如何工作的。

通常每个模型有一个ViewModel。这些ViewModels包含处理模型数据的逻辑。另一方面,每个视图也有自己的视图模型。这意味着:

class ModelA 
{
    bool TestValue{get;set;}
}
class ViewModelA<ModelA>
{
    ValueViewModel<bool> TestValue{get; private set;}

    public ViewModelA(ModelA model) 
    {
        base.Model = model;
        this.Initialize();
    }
}

class ModelB 
{
    string Username;
}
class ViewModelB<ModelB>
{
    ValueViewModel<string> Username{get; private set;}

    public ViewModelB(ModelB model) 
    {
        base.Model = model;
        this.Initialize();
    }
}

为了回答您的问题,ViewModel1引用ViewModelA和ViewModelB。因此,视图可以从
ViewModel1.ViewModelA.TestValue

获取数据。您可以在视图模型中使用多个模型。视图模型的目的是抽象出业务/数据层(即模型)


但是,使用多个模型通常表示视图太大。您可能希望将其拆分为用户控件(它们有自己的视图模型)。

一个视图模型可能而且在许多情况下确实使用多个模型。它本身就是你观点的“模型”

考虑一个用户输入其个人信息(包括地址)的配置文件屏幕。如果地址存储在“addresses”表中,其余存储在“profile”表中,则ViewModel将同时使用profile和address模型来创建统一的ViewModel


正如他在回答中提到的,很多时候,您可以使用用户控件来实现一对一的关系,但您也可以通过100%的时间尝试来引入不必要的复杂性。

我会确保您理解view、viewmodel和所有其他模型类之间的区别。ViewModel是填充了视图可以绑定到的数据的模型对象。它的存在只是为了向视图提供数据,这使得ViewModel对象单元可测试,并且整个业务逻辑与视图分离。因此,您可以完全开发业务逻辑,而无需使用视图本身,并且可以仅构建或使用另一个视图并绑定到ViewModel对象的属性来替换视图。例如,如果视图中充满了空文本字段,则可以将文本字段的内容绑定到视图模型的不同属性

通常实际上应该只有一个视图模型。但如果太复杂,可以使用绑定对象的子属性,如中所述


ViewModel可以从许多不同的源、业务对象、数据库等获取返回到视图的数据

在我对MVVM模式的理解中,唯一的实际需求是视图从ViewModel的属性获取其所有数据(可能通过绑定机制)。ViewModel是一个专门为该视图设计的类,负责根据需要填充自身。您可以将其视为视图的ActiveRecord

因此,在ViewModel中执行什么操作以获取其属性应显示的数据并不重要。您可以通过查询某些服务、读取一个或多个业务实体模型、现场生成或以上所有方式获得它。这是非常正常的需要所有这些东西的组合,使一个功能性的看法

正如在任何演示模式中一样,重点只是将在屏幕上显示某些数据的过程与获取该数据的过程分开。这样,您可以分别测试流程的每个部分

编辑:这里有一个小但希望完整的依赖流示例

// Model/service layer

public class MyModelA
{
  public string GetSomeData()
  {
    return "Some Data";
  }
}

public class MyModelB
{
  public string GetOtherData()
  {
    return "Other Data";
  }
}

// Presentation layer

public class MyViewModel
{
  readonly MyModelA modelA;
  readonly MyModelB modelB;

  public MyViewModel(MyModelA modelA, MyModelB modelB)
  {
    this.modelA = modelA;
    this.modelB = modelB;
  }

  public string TextBox1Value { get; set; } 

  public string TextBox2Value { get; set; }

  public void Load()
  {
    // These need not necessarily be populated this way. 
    // You could load an entity and have your properties read data directly from it.
    this.TextBox1Value = modelA.GetSomeData();
    this.TextBox2Value = modelB.GetOtherData();
    // raise INotifyPropertyChanged events here
  }
}

public class MyView
{
  readonly MyViewModel vm;

  public MyView(MyViewModel vm)
  {
    this.vm = vm;
    // bind to vm here
  }
}

// Application layer

public class Program
{
  public void Run()
  {
    var mA = new MyModelA();
    var mB = new MyModelB();
    var vm = new MyViewModel(mA, mB);
    var view = new MyView(vm);
    vm.Load();
    // show view here
  }
}
viewmodel包含“视图逻辑”-因此您希望在视图上显示的所有内容都通过viewmodel公开。如果您想显示来自不同“模型”的数据,那么您的viewmodel将放弃此选项,并且视图可以绑定到

mvvm的主要目的是btw单元测试。这意味着无需UI即可轻松测试视图逻辑

编辑:你为什么认为:

ViewModel在其构造函数中只有一个视图参数

编辑2:


顺便说一句,使用mvvm有两种主要方法,第一种是“视图优先”,第二种是“视图模型优先”。您当然可以将这两种方法混合使用,并根据需要选择最佳方法。

只需在视图中使用用户模型即可

public partial class User : Login
{
    public string Password { get; set; }

    public List<Customer> customer { get; set; }
}
公共部分类用户:登录
{
公共字符串密码{get;set;}
公共列表客户{get;set;}
}

在此情况下,继承了另一个模型登录,并且此模型中也使用了客户模型。

是什么让您认为ViewModel无法绑定到不同的数据源?视图仅通过依赖项注入包含在一个模型上。因此构造函数只接受一个模型。请重新阅读我的评论:是什么让你认为ViewModel(不是视图)不能绑定到其他不同的模型(不是ViewModels)是的,我指的是ViewModel,不是view。打字错误。很抱歉。ViewModel是视图的模型,因此它仅与视图直接相关。不要试图遵循规则,在模式和实践中没有严格的规则。嗯?你可能想把它重新写清楚一点。听起来好像你说一个视图应该有多个ViewModel。难道“每个视图都有自己的ViewModel”不可理解吗?对不起,f
public partial class User : Login
{
    public string Password { get; set; }

    public List<Customer> customer { get; set; }
}