5

我是 MVVM(和一点 WPF)的新手,在过去的几天里,我阅读了许多 Code Project 文章、博客文章和 Stackoverflow 问题。我的印象是,一旦从数据源(数据库)加载数据,数据绑定就可以很好地显示数据,并使模型与视图保持同步,同时更新视图中模型数据的所有其他外观。

但是我仍然不知道如何保存以及在验证之前应该如何正常工作。我有很强的 Windows 窗体和 ADO.NET 背景。我非常熟悉数据库访问层和视图更新的编码。那时,您有临时的临时数据,正在编辑,仅在视图中,以及模型类和数据库中数据的最后保存版本。模型类通常与数据库同步。它是包含尚未保存的数据的视图。

您还有一个保存按钮,它可以从控件中读取所有数据,在代码中对其进行验证,然后接受并将其保存到模型和数据库中,或者不更新模型并改为显示错误消息。如果出现错误,用户输入会保留在 UI 中以供用户更正。但是应用程序的其他部分无法看到它。并且您有一个取消按钮,它只会丢弃包含编辑控件的视图部分 - 模型仍然有效且未更改。

现在,数据绑定和 ViewModels 只是从模型类中公开数据,在 TextBox 中输入的内容会立即进入模型,无论它是否正确。IDataErrorInfo 仅此而已 - 提供信息。你可以看它或忽略它。唯一强制执行的硬验证是类型转换:您永远不能将非数字字符串更新为数字模型字段。但仅此而已。我将通过让 ViewModel 进行所有验证并从属性设置器对无效数据抛出异常来解决这个问题。这是实现已知行为的唯一方法。

但是数据的保存和丢弃到哪里去了?我什么时候才能真正将数据写回数据库?TextBox 的每次离开都会导致数据库写入,因此我不再需要显式的 Save 命令(并且只能通过 Undo 恢复)?我什么时候验证整条数据记录?我将如何处理模型和数据库不同步,由于数据绑定而导致无效输入立即传播到整个应用程序和所有视图?何时以及如何使用取消按钮丢弃任何用户输入,保持模型不变 - 或将其恢复到打开编辑器对话框之前的状态?

我觉得 MVVM 并没有为这些基本问题提供解决方案。我只是想念他们还是他们真的不存在?如果 MVVM 不能解决这个问题,那是什么?或者 MVVM 最好不要用于 WPF 中的数据编辑应用程序?

4

3 回答 3

6

MVVM 不会为您解决这些问题——您有灵活性(权力?负担?)以您选择的任何方式解决数据库写入问题。如果您需要在保存回数据库之前收集所有数据,您可以这样做 - 只需在 ViewModel 上添加一个绑定到 SaveCommand 的 Save 按钮,该按钮执行您的数据访问存储过程/实体框架更新方法/无论什么。如果您想单独记录每一位数据,那么您需要在其他地方调用数据访问过程(可能是视图模型上的属性设置器?)

本质上,MVVM 并不是一个完整的端到端软件模式。它只关注用户所看到的(列表框、文本框和按钮)与应用程序本身之间的通信。您的数据访问代码、序列化、存储、持久性,无论您在使用什么,以及无论您如何使用它,都保存在应用程序的 MVVM 端,在您的应用程序代码(模型)中。你可以随心所欲地写这个。

我目前正在编写一个应用程序,用户填写表格并点击保存或取消。保存和取消都是绑定到 ViewModel 上的命令的按钮。在 ViewModel 构造函数中,模型对象的属性被复制到 ViewModel 的属性中。保存时,ViewModel 的属性被复制回模型的属性并启动数据访问代码。在取消时,模型的属性被复制回 ViewModel 的属性。

class MyViewModel
{
   public MyViewModel(MyModel model)
   {
      this.Name = model.Name;
      this.Colour = model.Colour;
   }

   public string Name {get;set;}
   public string Colour {get;set;}

   // commands here that connect to the following methods

   public void Save()
   {
      model.Name = this.Name;
      model.Colour = this.Colour;
      model.SaveToDatabase();
   }

   public void Cancel()
   {
      this.Name = model.Name;
      this.Colour = model.Colour;
   }

}

这是一种简单的方法 - 当然,您需要投入INotifyPropertyChanged其中的其余部分,还有其他选择。但是我发现这种方法很容易理解正在发生的事情,并且是添加您可能需要添加的任何其他内容的良好基础。

于 2012-07-06T13:36:27.483 回答
1

使用 MVVM,您可以将视图中的控件绑定到 ViewModel 中的属性和命令。模型代表您的数据库。

可以通过多种方式验证用户输入。您可以限制文本框只接受某些数据,您可以在属性设置器等中验证数据等。

我不是数据库专家,但我会在我的 VM 中收集信息并在视图中的某处添加一个保存按钮,该按钮验证数据并将其写入数据库。取消按钮可以用模型(数据库)中的(未更改的)值覆盖 VM 属性。

(编辑:皮特说的话:)

于 2012-07-06T13:42:13.433 回答
0

我认为您将 ViewModel 与数据库混淆了,您的视图绑定到 ViewModel 中的对象,当离开 TextBox 时,TextBox 中的任何内容都将分配给仍在内存中的 ViewModel 对象。您将需要一个保存按钮,MVVM 只是一种将传统视图和代码分离的模式,用于解耦和简单的单元测试。单击保存按钮后,您仍然需要执行数据验证。要丢弃用户输入并恢复到以前的状态,您可以在编辑之前保存 ViewModel 数据,或者使用实体框架来跟踪和管理数据更改。

于 2012-07-06T13:41:43.493 回答