c# - WPF 标记扩展如何引发编译错误?

标签 c# wpf

某些标记扩展会引发编译错误。例如,如果找不到引用的类,StaticExtension (x:Static) 会引发编译错误。有人知道这个机制吗?它是嵌入到 XAML 编译器中还是自定义标记扩展可用的此类功能?

编辑:下面的 mfeingold 建议我需要查看 IVsErrorList 接口(interface),但我不能立即看到这将如何帮助某人白色生成编译时错误的标记扩展。有例子吗?

最佳答案

扩展 BAML 编译过程以记录其他错误

我去年遇到过同样的问题。我正在编写自己的扩展,我希望在某些情况下出现编译时错误,并发现仅从 ProvideValue 中抛出异常是行不通的,因为未调用 ProvideValue直到实际加载 XAML 并创建对象树。

我做了一些实验,发现 x:Static 的编译器错误消息是 BAML 编译器优化的副产品。 BAML 格式实际上具有特定类型的特定成员的概念,因此当 XAML 包含 x:Static 时,编译器实际上将其替换为直接引用成员而不是包含类型的特殊记录和方法名称。它通过明确识别 StaticExtension 类来做到这一点。 TypeExtension 也有类似的优化。

我搜索了允许我在 BAML 编译期间调用我自己的代码的 Hook ,但我没有找到任何 Hook 。 BAML 编译主要只是直接音译为对应于 XAML 的二进制格式,进行了一些特定的优化,但主要是忽略了它所看到的内容。

我最终在构建过程中添加了一个额外的步骤,根据 Microsoft.WinFX.targets 和其他内置目标文件对我的代码进行建模。此步骤扫描我的标记扩展的 XAML,检查参数,如果参数不正确则生成编译错误。这是完全独立于向 BAML 的转换完成的。当一切都说完之后,实现它需要几天的额外工作,但我学到了很多东西。

关于创建您自己的 .targets 文件的注意事项

如果您正在考虑添加自己的 .targets 文件,您应该知道,除非您将目标包含在本地计算机的 SafeImports 注册表项中,否则 Visual Studio 和 Expression Blend 都会提示任何包含您的 .targets 的项目。目标文件。此 key 需要计算机上的管理员访问权限才能更新。这可能是也可能不是问题,具体取决于您的部署方案。 (例如,机器范围的 MSI 安装可以修复它,或者如果您只有几台开发机器,您可以手动设置 key )。就我而言,这无关紧要,因为我已经需要自定义 .targets 文件来处理我在该项目中所做的其他一些事情。

从构建任务中记录错误

您不需要 IVsErrorList 在构建期间向 Visual Studio 添加错误(如果您这样做,您将无法正确支持命令行构建、Expression Blend 和其他工具)。

您需要做的就是从构建任务中调用 Log.LogErrror Log.LogWarning,如下所示:

public class CheckForErrorsInMyMarkupExtension : Task
{
  ... parameters here ...

  public override Execute()
  {
    ... code to load XAML and scan it for markup extension errors ...
    ... when you discover an error ...
      Log.LogError("I saw an error");
  }
}

关于c# - WPF 标记扩展如何引发编译错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1701895/

相关文章:

c# - unlockbits、lockbits 和 try-finally

c# - 如何更改 ASP.NET Core API 中的默认 Controller 和操作?

c# - 使用 Reflection.Emit 创建一个实现接口(interface)的类

CommandManager 的 WPF 性能问题

c# - 在 WPF 中打印带有动态数据的流文档

c# - 获取 tcp 套接字序列号和 ack 号

.net - 如何最好地处理 WPF 单选按钮?

wpf - 是否可以将自定义拼写检查字典添加到样式中?

wpf - 如何在WPF窗口中触发Usercontrol的Unload事件

c# - 根据 StartUp.cs 设置,Cookie 不会过期