C# XAML是否有用于调试模式的条件编译器指令?

C# XAML是否有用于调试模式的条件编译器指令?,c#,wpf,xaml,C#,Wpf,Xaml,对于XAML中的样式,我需要这样的内容: <Application.Resources> #if DEBUG <Style TargetType="{x:Type ToolTip}"> <Setter Property="FontFamily" Value="Arial"/> <Setter Property="FlowDirection" Value="LeftToRight"/> </St

对于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>

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


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

有趣的是,标准文档Office Open XML File Formats涵盖了如何在XML文档中处理此问题,XAML确实支持spec 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>
<window ... xmlns:Util="clr-namespace:MyNamespace.Utility" >
    <Label Util:DebugVisibility.IsVisible="True">
</window>
注释掉属性

XAML解析器团队SL4,WP7.1,WPF选择使用该规范来解决忽略属性的需求,而不仅仅是编造一些东西。这就是为什么一些默认XAML页面定义了“mc”名称空间。我确实认为,如果XAML有一天支持规范中允许加载替代内容的其余部分,那就太酷了


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

我最近不得不这样做,当我无法轻松找到任何清晰的示例时,它是多么简单,这让我感到惊讶。我所做的是将以下内容添加到AssemblyInfo.cs:

#if DEBUG
[assembly: XmlnsDefinition( "debug-mode", "Namespace" )]
#endif
然后,使用markup Compatibility命名空间的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模式,并且将出现d名称空间。这使得AlternateContent标记选择第一个代码块。如果未定义调试,则将使用代码的回退块

这个示例代码没有经过测试,但它与我在当前项目中使用的有条件地显示一些调试按钮基本相同


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

我觉得给出的答案不是最容易使用的。以下是我使用自定义可附加依赖项属性的解决方案:

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的使用方式如下:

<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>
<window ... xmlns:Util="clr-namespace:MyNamespace.Utility" >
    <Label Util:DebugVisibility.IsVisible="True">
</window>

我把它作为一个bool保存,以防你想在其中添加其他可见性逻辑。这是一个很好的简单切换,可以绑定并附加到任何控件

我需要在调试模式下使用不同的样式,以便在调试模式下执行更轻松的操作。VS error窗格不喜欢这样,尽管一切正常:当我将代码添加到AssemblyInfo.cs时,我的解决方案无法编译。找不到类型或命名空间名称“XmlnsDefinitionAttribute”。是否缺少using指令或程序集引用?。我能做什么?XmlnsDefinitionAttribute位于System.Windows.Markup命名空间中。此命名空间位于System.Xaml.dll程序集中,我相信在visual studio中创建WPF项目时会自动添加。如果在AlternateContent之间使用向IComponentConnector添加代码的功能。像OnClick这样的Connect方法事件处理程序,ConnectionID是否会完全锁定,InitializeComponent将在运行时失败,或者在事件发生时执行意外的操作注意,您可能需要针对自身标记mc Ignorable,即mc:Ignorable=d mcGood idea,但是实现可以简单得多。调试过程中,调试/释放显然不会改变,因此您不需要所有绑定/依赖性的东西。您所需要的只是Util中的静态变量Debug,调试时为True,否则为False。为了方便起见,第二个静态版本在调试时为False。然后注意:这个答案与条件编译不同;IsVisible=False表示视图对象是在没有布局调用的情况下创建的。这有一定的成本,虽然通常是一个小的-所以在某些情况下是可以的。对于这个关于替代样式的特定问题,IsVisible没有帮助。顺便说一句,如果您的代码基于您在其他地方看到的示例,您应该提供一个链接,以感谢其代码帮助您创建此示例的作者。它看起来很复杂,所以VS设计师可以看到这种变化,如前所述;如果这是复杂性的原因,那么您应该提到这一点。如果问题是关于备用视图内容,那么DataTemplateSelector可能是相关的,但它是关于备用样式的-没有备用样式的选择器。嗯,你可以创建两个单独的内容副本,使用不同的样式。。。但这听起来不像你想说的。