【问题标题】:Building a data entry form in wpf在 wpf 中构建数据输入表单
【发布时间】:2012-12-04 04:52:41
【问题描述】:

我正在尝试在 wpf 中构建数据输入表单。要执行验证,我显然需要在网格的数据上下文中附加一个对象。但是我还没有创建一个,我怎么能拥有一个呢?

它是如何工作的?

例如,我有一个带有数据网格的屏幕。数据网格包含从成员资格获得的用户。网格上方是一个按钮:添加用户。单击时会出现一个新窗口,可以输入以下内容:用户名、密码、电子邮件。对文本框执行验证以查看它们是否为空。现在,据我了解,它的工作方式是将对象附加到窗口(datagrid datacontext)。但是当它还不存在时,我怎么能附加它呢?

【问题讨论】:

    标签: wpf


    【解决方案1】:

    这是MVVM design patterns非常有用的情况。

    每个 WPF 视图都有一个对应的视图模型对象,视图中的属性绑定到该对象。所以你的带有数据网格的窗口有一个视图模型 - 它的DataContext - 并且视图模型具有绑定到视图中属性的属性 - 例如数据网格中的ItemsSource 绑定到一个集合(见注1)。

    “添加用户”命令(在窗口的视图模型中实现为RelayCommand)创建一个新视图(新窗口)及其对应的视图模型对象(新用户),设置视图的@987654327 @ 到视图模型,并调用 ShowDialog 来显示窗口。 (见注释 2。)如果用户接受新对象,ShowDialog 返回 true,命令中的逻辑获取视图模型对象(现在包含用户所做的任何更改)并使用其中的信息创建一个新模型对象并将其添加到模型中。如果用户取消,ShowDialog 返回 false,并且该命令丢弃视图模型对象而不创建新的模型对象。

    注意1:这里的集合可能是模型对象的集合,也可能是视图模型对象的集合。这取决于您是否需要模型中没有的任何东西来在数据网格中显示模型对象。在这种情况下,网格中的对象通常是对话框的视图模型——也就是说,视图模型对象具有在网格中显示和在对话框窗口中修改的属性。另一方面,如果网格所做的只是显示模型中的数据,则可能不需要中间对象。

    注意 2: 让命令创建 WPF 窗口违反了核心 MVVM 设计原则,即视图模型不应创建 WPF 对象。这个原则的原因很简单:你不能为这个命令构建一个自动化的单元测试,因为它只会抛出一个对话框并等待。有各种不同的方法 - 例如,参见this questionJosh Smith's blog post on the Mediator pattern - 所有这些方法都涉及将实际对话窗口的创建和显示委托给一个单独的服务,该服务可以为单元模拟测试。如果您不想预先选择其中一种方法,则可以在使此方法正常工作后将其中一种方法改进到您的应用程序中。

    【讨论】:

      【解决方案2】:

      这里的想法是您应该附加一个与您的业务模型略有不同的对象。在您的情况下,它不会 UserInfo (或您为网格中的用户提供的任何内容)。它将是其他一些类,更适合编辑。在MVVM 中,此类将是ViewModel。这个类与你的普通用户类相比会有一些不同,例如它可能有一些可以为空的属性(当你还没有设置它们时)。这个类也将处理验证。您应该在创建编辑器窗口的同时实例化此类并将此类的实例放入Window.DataContext

      【讨论】:

      • 啊哈。这是有趣的!我(仍然有点)对这件事应该如何工作感到困惑。我只是想要一个包含一些字段的表单,填写数据,然后 -> 数据库。我对此感到惊讶,我听说需要填充数据上下文。我不明白,因为我只是没有对象(或者我认为)绑定到数据上下文。
      【解决方案3】:

      嗯,这个问题有很多,但我刚刚创建了一个带有三个数据网格的屏幕(在这种情况下我使用 Telerik),每个数据网格下都有一个添加到网格的按钮。没有具有三个数据网格的窗口有它自己的视图模型。每个“弹出窗口”都有自己的视图模型,在这种情况下,所有这些都是用户控件,我只是创建一个新窗口并设置 window.content 并调用显示对话框。

      通过“事件”促进通信 - 不是您在 .NET 中习惯的标准事件,但在这种情况下,我使用的是 Prism,它是 CompositePresentationEvent 类。当用户完成创建他们的新对象时,他们单击添加,我以“有效负载”作为他们创建的对象触发此事件。具有三个网格的主窗口侦听该事件并具有处理它的方法,在本例中将其添加到 ObservableCollection 中,这是我将网格绑定到的对象。

      如果我是你,我会研究现有的各种框架,Prism、MVVM light 等......同样,你的问题似乎相当广泛,我试图给出一个概述,但我没有详细介绍,如果您研究某种框架,我认为它会为您清除很多这些细节。

      【讨论】:

      • 好吧,也许我应该用不同的方式表述它:当单击添加按钮时,会弹出一个新窗口,您可以在其中输入例如一个新用户,(例如)新窗口中包含这些字段的网格的数据上下文应该绑定到您正在为其填写字段的对象,对吗?我实际上只是想知道在填写表单时应该将一个空对象绑定到窗口的假设是否正确,假设是一个新产品或用户。
      【解决方案4】:

      当用户点击 Add New 时,为您的对象创建一个新的空白副本,并将 datacontext 设置为该新对象。

      设置某种标志来标识它是一个新对象。这可以是 Id 为 NULL、0、-1 等,也可以是设置为 New 的 ObjectState 属性。这样你的所有验证规则都适用,一旦用户点击保存,你就会知道插入而不是更新

      【讨论】:

      • 是的,也许是这样的。原因是我可以验证用户输入。起初我在寻找类似 asp.net 的验证器控件之类的东西,但它们在 wpf 中不存在。试图弄清楚如何验证空文本框,人们一直说我需要设置我的数据上下文。
      • 通常,您将 DataContext 绑定到的对象将实现IDataErrorInfo,这允许您为您的类编写一些由 WPF 自动获取的验证代码。所以验证存在于被绑定的对象中,而不是 UI 控件中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 2013-05-14
      • 1970-01-01
      • 2021-02-06
      相关资源
      最近更新 更多