XAML是否有针对调试模式的条件编译器指令?

时间:2012-01-04 18:54:45

标签: c# wpf xaml

对于XAML中的样式我需要这样的东西:

<Application.Resources>

#if DEBUG
    <Style TargetType="{x:Type ToolTip}">
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FlowDirection" Value="LeftToRight"/>
    </Style>
#else
    <Style TargetType="{x:Type ToolTip}">
        <Setter Property="FontFamily" Value="Tahoma"/>
        <Setter Property="FlowDirection" Value="RightToLeft"/>
    </Style>
#endif

</Application.Resources>

4 个答案:

答案 0 :(得分:105)

我最近不得不这样做,当我无法轻易找到任何明确的例子时,我感到很惊讶。我所做的是将以下内容添加到AssemblyInfo.cs:

#if DEBUG
[assembly: XmlnsDefinition( "debug-mode", "Namespace" )]
#endif

然后,使用markup-compatability命名空间的AlternateContent标记根据该命名空间定义的存在选择您的内容:

<Window x:Class="Namespace.Class"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="debug-mode"

        Width="400" Height="400">

        ...

        <mc:AlternateContent>
            <mc:Choice Requires="d">
                <Style TargetType="{x:Type ToolTip}">
                    <Setter Property="FontFamily" Value="Arial"/>
                    <Setter Property="FlowDirection" Value="LeftToRight"/>
                </Style>
            </mc:Choice>
            <mc:Fallback>
                <Style TargetType="{x:Type ToolTip}">
                    <Setter Property="FontFamily" Value="Tahoma"/>
                    <Setter Property="FlowDirection" Value="RightToLeft"/>
                </Style>
            </mc:Fallback>
        </mc:AlternateContent>

        ...
</Window>

现在,当定义DEBUG时,还将定义“debug-mode”,并且将出现“d”命名空间。这使得AlternateContent标记选择第一个代码块。如果未定义DEBUG,则将使用Fallback代码块。

此示例代码未经过测试,但它与我当前项目中有条件地显示一些调试按钮的内容基本相同。

我确实看到一篇博客文章,其中包含一些依赖“Ignorable”标签的示例代码,但这种方法似乎不太清晰且易于使用。

答案 1 :(得分:2)

您可以使用模板选择器。 DataTemplateSelector类是您编写的代码。使用您覆盖的模板选择方法,您可以放置​​预处理器指令。

http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx

答案 2 :(得分:2)

这在WPF / Silverlight / WP7中是不可能的。

有趣的是,标准文档ISO/IEC 29500涵盖了如何在XML文档中处理此问题,而XAML确实支持该规范mc:Ignorable中允许我们执行的项目之一这样的事情:

<Page xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:c="Comments"
      mc:Ignorable="c">
    <Button Content="Some Text"
            c:Content="Some other text" />
</Page>

注释掉属性。我认为如果有一天XAML支持允许加载替代内容的其他规范,那将会很酷。

Blend使用mc:Ignorable属性来支持设计时功能。

答案 3 :(得分:1)

我觉得给出的答案并不是最容易使用的。这是我使用自定义附加属性的解决方案:

using namespace Utility{
    public static class DebugVisibility
    {
        public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.RegisterAttached(
    "Debug", typeof(bool?), typeof(DebugVisibility), new PropertyMetadata(default(bool?), IsVisibleChangedCallback));

        private static void IsVisibleChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var fe = d as FrameworkElement;
            if (fe == null)
                return;
#if DEBUG
            fe.Visibility = Visibility.Visible;
#else
            fe.Visibility = Visibility.Collapsed;
#endif
        }

        public static void SetIsVisible(DependencyObject element, bool? value)
        {
            element.SetValue(IsVisibleProperty, value);
        }

        public static bool? GetIsVisible(DependencyObject element)
        {
            return (bool?)element.GetValue(IsVisibleProperty);
        }
    }
}

和xaml将像这样使用:

<window ... xmlns:Util="clr-namespace:MyNamespace.Utility" >
    <Label Util:DebugVisibility.IsVisible="True">
</window>

如果您想在其中添加其他可见性逻辑,我会将其保留为bool。这是一个很好的简单切换,可以绑定并附加到任何控件