在编译时验证XAML中的数据绑定

时间:2009-12-10 23:21:29

标签: wpf data-binding mvvm

我正在开发基于WPF的应用程序。环境是VS2008 SP1与.NET 3.5 SP 1。 在我们的开发中,我们广泛使用MVVM模式。

即。应用程序开发人员编写模型和ViewModels(C#),然后UI开发人员将使用WPF绑定(XAML)编写视图。应用程序开发人员还在ViewModel之上编写单元测试。 我们正在使用持续集成方法,我们正在构建并执行每个修改的单元测试

问题是缺少XAML中数据绑定正确性验证的过程或工具。 例如:

  1. App开发人员编写属性 NmberOfApples 和单元测试以检查其正确行为
  2. UI开发人员创建用户控件并将其绑定到属性
  3. App开发者发现该属性拼写错误并将其名称修改为 NumberOfApples
  4. 任何C#代码中的编译时错误都会使用 NmberOfApples 属性,这样的错误很容易被捕获(持续集成)
  5. XAML文件中的数据绑定不会被验证,它将是运行时错误
  6. 我的问题是“是否有任何工具或方法可以帮助我们在编译时验证XAML中数据绑定的正确性?”

6 个答案:

答案 0 :(得分:9)

article中讨论了您的问题的解决方案。

基本思想是创建一个静态(c#)类的ViewModel MetaData集,其中包含您可以在xaml中使用的ViewModel类属性的字符串值。本文介绍了如何使用T4文本生成来创建这些静态元数据类。您可以使用您偏好的任何代码生成工具。

因此您的VM具有以下内容:

namespace Mine
{
  public class MyViewModel
  {
    public int MyInt {get;set;}
   public string MyString {get;set;}  
  }
}

你的代码生成会创建这个:

namespace Mine.MetaData
{
  public static class MyViewModelMetaData
  {
    public const string MyInt = "MyInt";
    public const string MyString = "MyString";
  }
}

然后在你的xaml中你将命名空间添加到你的xaml并将你的控件绑定到元数据类

<TextBox Text="{Binding Path={x:Static Metadata:MyViewModelMetadata.MyInt}}"/>

如果您使用像resharper这样的加载项,那么它将为您提供静态类的属性的智能感知,并且还因为您在静态类中引用精确属性,当静态类重新生成时xaml不应该编译。

它非常光滑,我觉得很棒,它有机会让大多数人保持理智,但你的里程可能会有所不同。 :)

编辑:

顺便说一句,我不买“ViewModels与视图紧密耦合”。在我看来,视图与它们的ViewModel有着千丝万缕的联系,但它应该只是一种方式。 ViewModels应完全独立于任何视图实现。它就像ViewModel是接口,View是具体实现的类。因此,我没有在我的ViewModel中添加任何特定于WPF的属性(例如,可见性枚举),因为这使我使用WPF永恒(这不是一件坏事:)),但它会影响维护。

答案 1 :(得分:2)

如果您安装ReSharper,您将获得的(许多)功能之一是“代码检查”。此检查将检测到的一个问题是绑定无法解析为数据上下文中的属性。您可以轻松过滤“检查结果”窗口以仅显示这些问题。

请注意,您必须在XAML资源中明确说明视图模型的类型才能使其生效。

Example of ReSharper inspections

答案 2 :(得分:1)

有许多可以理解的好方案,实际上需要这种行为。在任何情况下,根据设计,绑定会吞下错误,这也是您无法找到任何可以帮助您解决问题的原因。

我见过的最好的事情是一个异常验证处理程序,它将显示绑定错误: http://msdn.microsoft.com/en-us/library/system.windows.controls.exceptionvalidationrule.aspx

对此的论点是视图和ViewModel意味着分离到View可以用于多个ViewModel的点。它还有助于视图的“可弯曲性”,因此理论上,设计器类型可以设置视图样式,而不会在执行时遇到大量错误。我意识到这可能不适合你的过程,但这就是故事。

答案 3 :(得分:1)

自从问到并回答了原始问题以来已经过去了几年,但正如我刚刚检查过的那样,解决方案可能会变得更加简单。 ReSharper似乎提供了正确的Intellisense而无需生成接受答案中提到的静态类。

但我还没有见到接受的答案中所述的编译时错误。我甚至尝试使用[XamlCompilation(XamlCompilationOptions.Compile)]无济于事。如果我错过了什么,请帮我纠正。

答案 4 :(得分:0)

目前,我们正在按照本文Caliburn中介绍的方式使用Testing Bindings In WPF和单元测试。这个解决方案的缺点是,UI开发人员编写的代码只对验证绑定有意义,如果MS(或某人)编写XAML验证编译器,则可以省略。

答案 5 :(得分:-1)

我同意之前的回答。这是“按设计”,在编译时无法检查它。

我也发现它很痛苦。

我找到的最好也是唯一的方法是在运行时检查Visual Studio调试输出。打开包含它的窗口后,将立即打印任何绑定错误。

我同意,如果你认为这是一个糟糕且不可靠的方法,但如果你没有大量的窗口它应该可以工作。您可以创建一个半正式的测试练习,偶尔打开一个专门查看绑定错误的窗口。