【问题标题】:"Conditional Compile" in XAML?XAML 中的“条件编译”?
【发布时间】:2014-02-07 21:27:09
【问题描述】:

我们有一个内部使用的程序来测试和验证我们销售的工业控制产品。我们希望能够向某些客户提供缩小版或轻量级版本。

我们的程序是使用 C# 和 WPF(因此是 XAML)编写的。使用条件编译功能可以轻松完成只为在我们的工厂中使用而构建的 C# 代码部分,例如,

#if FACTORY
    // our in-house code . . .  
   . . . 
   . . . 
#endif

但是我们如何才能为我们程序的 XAML 部分完成类似的事情呢?

注意: **有关此主题的 Stack Overflow 问题,有人发布了带有链接的简洁答案,但该链接似乎与该问题无关。因此,不要以此为基础将其视为重复,因为这不能回答问题。* XAML Conditional Compilation

【问题讨论】:

  • 您能否添加更多有关您要禁用的功能类型的详细信息?因为 XAML 仅适用于 define the UI - 我无法想象您想要有条件地编译 XAML 的哪些部分。
  • answer 到其他看起来很有希望的问题。
  • 有些按钮和其他 UI 组件我们希望仅在工厂中可用和可见。

标签: wpf xaml


【解决方案1】:

链接的问题/答案中说明的技术可能会在某种程度上对 XAML 元素进行有条件的处理,但我认为它不会为您提供您所追求的确切内容。

还有另外两个选项可能更适合您的需求:程序化条件编译和构建时条件包含。

对于程序化条件编译,您可以在视图后面的代码中使用常规条件编译(最好是因为它是您正在影响的 UI 元素)或视图模型(不是那么纯粹,但如果您必须包含,则完全可以接受它在多层中)。此条件编译可用于更改从属性返回的值(通过更改编译并因此执行的行)或通过消除代码块(这很笨重但仍然有效),然后您可以拥有一个 XAML DataTrigger有一个expression dependent on the conditionally compiled code

另一个选项是指定 control templates in a XAML resource file 并以编程方式选择它们或使用 ItemGroup expression in your proj file 中的 MSBuild 属性来控制构建中包含哪些文件。结合您的模型/视图模型中的常规程序化条件编译,这将为您的问题提供一个很好的干净解决方案 - 事实上,使用此选项您甚至可能不需要程序化条件编译。

TemplateSelector 也可能有帮助,但 IMVHO 有点肮脏。 TemplateSelector 应该根据 type 交换模板,但您也可以利用它来包含额外的代码来确定要使用的模板 - 这可能是包含条件编译代码的好地方。

【讨论】:

  • +1 用于指定模板,例如控件模板/用户控件等。
  • 另一个建议是 put forward by Tomer Sharman 涉及附加属性。尽管我相信内容是在运行时选择的,但它并不是真正的条件编译。不过,这是另一个值得考虑的选择。
【解决方案2】:

我会使用 XSTL 转换,this MSDN article 解释了如何在编译时应用它们。应该可以设置转换以去除预处理器标签内的部分(this SO question 似乎只是显示了这一点),尽管我可能自己将它们放入 cmets 中,这样您就不会破坏 Visual Studio 设计器。还有this SO question,它展示了如何将处理器指令作为常规 XML 标记包含在内,您可以再次将其嵌入到 XAML 中。

【讨论】:

    【解决方案3】:
    1. 定义编译器常量FACTORY。

    2. 创建标记扩展类:

      using System;
      using System.Windows.Markup;
      
      namespace Conditional 
      {
          public class Condition : MarkupExtension 
          {
              public object MyFactory { get; set; }
              public object Other { get; set; }
      
              public override object ProvideValue(IServiceProvider sp) 
              {
              #if FACTORY
                  return this.MyFactory;
              #else
                  return this.Other;
              #endif
              }
          }
      }
      
    3. 在 XAML 标记中:

      • 导入命名空间:
      xmlns:conditional="clr-namespace:RootNamespace.Conditional"
      • 在需要条件 XAML 标记的地方插入此代码块:
      条件:条件>

    【讨论】:

    • 谢谢!虽然此解决方案有效,但它需要在 xaml 中插入所有可能的条件(否则它会引发空引用异常)。你知道避免这种情况的方法吗?谢谢
    猜你喜欢
    • 2010-11-15
    • 2011-05-16
    • 2020-07-02
    • 1970-01-01
    • 2014-12-02
    • 2018-03-14
    • 2023-03-04
    • 2012-10-08
    • 2012-06-23
    相关资源
    最近更新 更多