XAML中的“条件编译”?

时间:2014-02-07 21:27:10

标签: wpf xaml

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

我们的程序是用C#和WPF(因此是XAML)编写的。使用条件编译功能(例如

)可以轻松完成仅在我们工厂中构建的C#代码部分
#if FACTORY
    // our in-house code . . .  
   . . . 
   . . . 
#endif

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

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

3 个答案:

答案 0 :(得分:2)

链接问题/答案中说明的技术可能会在某种程度上提供有条件的处理的XAML元素,但我认为它不会完全给出你所追求的内容。< / p>

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

对于程序化条件编译,您可以在视图后面的代码中使用常规条件编译(最好是因为它是您正在影响的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 交换模板,但你也可以利用它来包含额外的代码来确定要使用的模板 - 这可能是包含有条件编译代码的好地方。 p>

答案 1 :(得分:1)

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

答案 2 :(得分:0)

  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标记的地方插入此代码块:
    <ViewBox>
        <conditional:Condition>
            <conditional:Condition.MyFactory>
                <TextBlock Text="This is My Factory"/>
            </conditional:Condition.MyFactory>
            <conditional:Condition.Other>
                <TextBlock Text="this is other" />
            </conditional:Condition.Other>
        </conditional:Condition>
    </ViewBox>